Compatibile con Xcode 8

Segue ed Unwind Segue in Swift. Passare dati avanti e indietro tra ViewController

ENTRA NEL NOSTRO GRUPPO FACEBOOK

In tutti i tutorial che ti ho fatto vedere, avrai sicuramente notato, che nascono e muoiono utilizzando esclusivamente un solo ViewController.

Il solo pensare di poter concentrare un’app in un solo ViewController è da folli, infatti ormai nessuno pensa a quest’approccio e preferisce, come più volte ribadito nelle lezioni del mio corso gratuito sul linguaggio Swift, dividere tutto in sotto problemi o in questo caso ViewController.

Ed infatti, quello che farai in questo tutorial sarà imparare a passare le informazioni tra ViewController con i Segue ed Unwind Segue in Swift. Cos’è un Segue? lo scoprirai tra poco. Per ora ti basta sapere che il processo di comunicazione tra ViewController è universale, cioè potrai applicarlo a qualsiasi tipologia di progetto.

In modo abbastanza semplice ti posso dire che:

  • Un Segue è l’operazione che ti permette di spostarti da un ViewController A ad uno B che si trova in una posizione successiva rispetto alla partenza.
  • Un Unwind Segue è l’operazione inversa del Segue. Permette di ritornare indietro, anche portando delle informazioni. Cioè puoi tornare indietro da B ad A e contemporaneamente, se vuoi, puoi trasportare delle informazioni.

Imparerai ad utilizzare i Segue e gli Unwind Segue creando una semplice applicazione composta da due ViewController. I due VC (ViewController) hanno la stessa grafica. Posseggono un TextField, una Label ed un Button. Premendo il bottone nel primo VC si passa il testo messo nella TextField del primo nella Label del secondo VC. Mentre dal secondo VC si eseguirà lo stesso passaggio in modo inverso.

segue ed unwind segue in swift

Esistono diversi sistemi per passare le informazioni e per navigare tra i ViewController. Quello che ti farò vedere è il più semplice che esista. Se ti va di approfondire il discorso, nel mio corso di sviluppo applicazioni iOS ho scritto un intero modulo riguardo i passaggi di informazioni.

Pronto? allora vediamo insieme come utilizzare i Segue ed Unwind Segue in Swift.

Interfaccia

Crea un nuovo progetto da File\New\Project… seleziona iOS, Application e Single View Application. Dai un nome al progetto, seleziona come linguaggio Swift e deseleziona tutte le restanti spunte.

Dal Project Navigator, seleziona il Main.storyboardtrascina un nuovo ViewController accanto a quello già presente:

Aggiungere un nuovo ViewController swift

Un ViewController, come la stessa parola suggerisce, è un controller di View. Quindi la grafica, gli elementi come bottoni, TextField etc.., vengono gestiti dal Controller.

ViewController

Il codice della tua interfaccia lo scrivi nel file ViewController,swift, questo ha una classe omonima che gestisce gli eventi che l’utente genera con l’interfaccia che hai creato dallo storyboard.

Quindi il ViewController è una sorta di gestore e controllore degli elementi grafici dell’applicazione. La suddivisione degli elementi di un progetto in tanti componenti, come il Controller ad esempio, fa parte delle specifiche del pattern di programmazione Model-View-ControllerSe ti va di approfondire questi concetti, ne ho parlato dettagliatamente nel mio corso di sviluppo applicazioni iOS con il linguaggio Swift.

Adesso seleziona il ViewController di sinistra, cambia il colore di background dall’Attributes Inspector (il pannello di destra) e aggiungi la TextField, una Label ed un Button come vedi nello screen sotto. Lo stesso passaggio eseguito per il ViewController di destra. Magari cambia il colore di background in modo da capire meglio dove ti trovi.

Nell’altro ViewController inserisci quattro Label. Due serviranno solo da corredo mentre gli altri prenderanno il valore delle informazioni che l’utente inserirà nel primo ViewController. Sistemali come preferisci:

Segue e Unwind in Swift interfaccia app

Quindi, l’utente inserirà gli elementi nel primo ViewController e, tramite il sistema di passaggio informazioni, verrà modificato l’aspetto del secondo ViewController grazie alle informazioni passate.

Auto LayoutStack View

Prima di avviare l’applicazione, devi sistemare l’Auto Layout. Ti ricordo che l’Auto Layout è quel sistema che ti permette di creare delle interfacce che vadano bene per tutti i tipi di dispositivi iOS, dall’iPhone 6S Plus all’iPad Pro.

Per sistemare correttamente l’applicazione ho preferito utilizzare le Stack View (introdotte in iOS 9) per velocizzare la creazione dell’interfaccia:

Segue e Unwind in Swift interfaccia e stackview

Lascio a te il compito di sistemare l’altro ViewController. Se già adesso hai alcuni problemi a seguire il tutorial, ti consiglio di partire da qualcosa di più semplice per poi ritornare qui più avanti:

A fine lezione trovi il download del progetto completo.

Il Navigation Controller

Come ti dicevo esistono diversi sistemi per poter navigare tra i ViewController dell’applicazione, quello che ti farò utilizzare io si chiama Navigation Controller e gestirà per te alcuni processi che avvengono durante la fase di spostamento tra i VC.

Il Navigation Controller è simile ad un View Controller solo che agli occhi dell’utilizzatore è invisibile. In realtà non è obbligatorio, però porta con se alcuni vantaggi utili per quanto riguarda le applicazioni composte da più View Controller (se vuoi approfondire ho scritto un intero modulo nel mio corso di sviluppo app).

Una tra questi vantaggi è la top bar automatica. Questa top bar permetterà al Navigation Controller di inserire, in automatico, il bottone per il ritorno indietro.

Seleziona il View Controller di colore verde e, nella barra del menu in alto, seleziona Editor\Embed In\Navigation Controller (l’immagine si riferisce ad un altro progetto ma il succo è lo stesso):

embed in navigation controller

Se tutto è andato per il verso giusto, dovresti vedere un NavigationController collegato con una freccia al ViewController di colore verde. Se dovessi avere dei problemi, per favore scrivi un commento così da vederlo insieme.

Navigation Controller

La prima freccia a sinistra, che punta sul Navigation Controller, ti informa che da qui inizierà la tua applicazione. Dato che il Navigation Controller è uno strumento non visibile, ti porterà direttamente nel View Controller a lui collegata.

La freccia che sta tra il Navigation Controller ed il View Controller Verde si chiama Segue di Relationship Root View Controller e definisce quale VC sarà visualizzato come primo dal Navigation Controller.

Da notare che la connessione con il Navigation Controller ha aggiunto al View Controller che effettivamente verrà visualizzato, la top bar di navigazione. Se la selezioni potrai aggiungere un Titolo o un messaggio personalizzato.

Cos’è un Navigation Segue

Un segue, o UIStoryboardSegue, è l’oggetto che permette ad un’applicazione di passare da un View Controller ad un altro e viceversa. 

Già tu hai creato un Segue in maniera indiretta quando hai aggiunto il NavigationController (la freccia che collega il NC al VC è un segue di tipo Root). Adesso però è arrivato il momento di imparare a crearli per connettere due VC della tua app.

Lo dico già da adesso. L’operazione che ti illustrerò non può essere fatta al contrario. Cioè, un segue può essere creato solo se si va da A a B e non viceversa. Ricordati questa proprietà perché se dovessi farlo, manderesti in autodistruzione l’applicazione. 

Dato che da un View Controller potrebbero partire più Segue, ognuno di questi è contraddistinto da un ID o Identifier. Questo Identifier, dal codice, potrà essere utilizzato per riferirsi al segue desiderato e quindi al Controller in cui spostarsi. Inoltre i Segue offrono delle animazioni che si attivano per rendere più piacevole il passaggio da un Controller ad un altro.

Per creare un Segue, seleziona il View Controller, premi Ctrl+Click sinistro (come per creare connessione con il codice) e trascina la freccia verso l’altro View Controller:

Segue Swift

Il menu generato, il Manual Segue, ti chiede quale animazione vuoi usare nel passaggio dal Controller Mittente al Controller DestinatarioIo ho scelto Show.

Non ho scelto Show a caso, potevo anche scegliere Show Detail ed il motivo risiede nella presenza del Navigation Controller. Il Navigation Controller gestisce la navigazione tra i vari VC. Questo si comporta come un contenitore dove al suo interno troviamo tutti i VC che hanno una relazione con il NC (Navigation Controller).

Infatti, oltre ad aver creato un Segue, grazie al Segue di tipo Show, hai reso il Controller destinatario figlio del Navigation Controller. Anche se c’è un VC che lo separa dal NC, il VC di colore blu è comunque gestito dal Navigation Controller. Infatti anche l’ultimo aggiunge la Navigation Bar in maniera automatica.

Solo cambiando il tipo di Segue in uno diverso dai due Show si perde la parentela con il Navigation Controller. Puoi fare una prova mettendo un nuovo VC e aggiungendo un Segue di tipo Present Modally.

Ricordati che il Navigation Controller non è obbligatorio per la navigazione tra i View Controller. Puoi creare i Segue anche senza la sua presenza. Se vuoi capire meglio le differenza tra queste scelte, puoi seguire il mio corso di sviluppo applicazioni iOS.

Segue Identifier

Dato che un Controller può avere più Segue è giusto che ognuno di essi abbia un identificatore.

Per impostare un identifier, dallo storyboard, seleziona la freccia del segue da trattare e dall’Attribute Inspector metti come identifierdetailSegue. Da questo menu puoi cambiare anche il tipo di Segue:

Segue Identifier

Puoi avere N Segue che partono da un ViewController e che arrivano ai punti più disparati dell’applicazione. L’importante è assegnare ad ognuno di questi un Identifier univoco in modo che da codice tu possa richiamare quello corretto che ti porterà da X a Y correttamente.

condividi xcoding

Sarei davvero felice se contribuissi al mio progetto semplicemente mettendo un mi piace o follow alle mie pagine

[addtoany]

Grazie davvero :-)

PerformSegue e Prepare linguaggio Swift

Crea un nuovo file dal Project Navigator, seleziona Cocoa Touch Class, metti su nome SecondViewController, subclass della UIViewController, assicurati di aver selezionato il linguaggio di programmazione Swift e premi su Create.

N.B. PerformSegueWithIdentifier é stato sostituito in swift 3 con performSegue(withIdentifier: String, sender: Any?), mentre prepareForSegue é stato rimpiazzato con il metodo prepare(for segue: UIStoryboardSegue, sender: Any?)

Il nuovo controller creato lo assocerai alla ViewController che hai aggiunto allo storyboard. Torna lì, seleziona il ViewController, vai nell’Identity Inspector e imposta come Class la SecondViewController:

Add new VC e Identity Inspector

Ricordati che ogni ViewController che inserisci nel progetto deve avere una Custom Class che la gestisce. Altrimenti non potrai creare Outlet o Action con gli elementi che vi hai inserito nello storyboard.

Ed infatti, il secondo passaggio che devi seguire è quello di creare le Outlet e le Action per ogni elemento dell’interfaccia. Crea due Outlet, una per la Label ed una per la TextField ed infine una Action per il bottone. Non ti ricordi come creare le connessioni? visita questo tutorial: La prima applicazione per iOS con il linguaggio swift.

Schermata 2016-05-26 alle 12.26.52

Nell’immagine, a sinistra hai il codice del primo ViewController e a destra quello del secondo. Rimembrati che non basta scrivere il codice per creare le connessioni, devi materialmente collegare ogni Outlet/Action al proprio elemento grafico.

Il performSegue e l’invocazione di un Segue

In questo momento hai un Segue che collega il ViewController al SecondViewController. Questo UIStoryboardSegue ha anche un Identifier che hai creato nel paragrafo precedente. Grazie a questo Identifier tu sei in grado, dal tuo codice, di richiamare il segue per attivare la navigazione verso il VC di destinazione corretto.

Il metodo per attivare un segue è il performSegue che ha due parametri:

  • Il primo è una stringa che identifica il segue da accendere tramite l’Identifier
  • Il secondo, chiamato sender, è un Any opzionale (Any?) che identifica l’oggetto che invoca questo segue (l’utilità di questo parametro è spiegato nel corso iOS).
Quindi, se nella Action del bottone del primo ViewController, scrivi:
Il tuo performSegue sta andando a chiamare il Segue che hai creato nello storyboard che ha per Identifier la stringa “showSecondVC“. Nel caso non esistesse, l’applicazione andrebbe in crash.

Nell’esempio si notano meglio i benefici del Navigation Controller. Senza saresti riuscito comunque ad utilizzare il Segue ed il performSegue (puoi usarli indifferentemente dalla presenza o meno del NC) però, non avresti avuto la TopBar con il bottone già pre impostato per tornare indietro.

Il prepare e l’invio di informazioni al VC di destinazione

Quando viene attivato un segue, grazie al metodo performSegue, il ViewController può gestire il passaggio tra i due View Controller grazie ad un altro metodo chiamato prepareForSegue

Prima che il ViewController A raggiunga il ViewController B con il Segue, c’è un frangente del passaggio in cui i due VC entrano in “contatto”. Un po’ come quando stai passando da una stanza all’altra di casa tua. Quando varchi la porta, se rimani nel mezzo, sei sia dentro la prima stanza che dentro la seconda.

Il prepare rispecchia esattamente questo concetto. All’interno del metodo prepare riesci ad accedere ai contenuti del ViewController di destinazione. Grazie a questa proprietà, nel metodo prepare del ViewController di partenza, potrai modificare e passare i contenuti al ViewController di destinazione del segue.

Il metodo che devi aggiungere nel tuo ViewController di partenza è il seguente:

Però, il ViewController di destinazione, non essendo ancora visualizzato sullo schermo non ha le sue Outlet inizializzate. Quindi, non potrai direttamente passare a queste i valori del VC di partenza. Come dire che quando stai per entrare nella stanza, questa ha la luce spenta e quindi non vedi dove stanno i vari elementi della stanza (come il comodino ecc).

Per questo motivo, se vuoi inviare delle informazioni dal VC A al VC B, quest’ultimo deve avere delle variabili d’appoggio in cui poter trasferire le informazioni che poi l’interfaccia caricherà. Spostati nel ViewController di destinazione, cioè il verde e dato che vuoi passare il testo contenuto nella textField alla sua Label, crea una proprietà di tipo String.

Adesso torna al ViewController di partenza dove hai aggiunto il prepare. Nel metodo prepare puoi recuperare l’istanza del ViewController di destinazione (grazie alla proprietà destinationViewController) e, di conseguenza, accedere a quella famosa variabile d’appoggio per la trasmissione dei dati.

Il metodo prepare ha un parametro, segue, che ti permette d’accedere al segue che è stato invocato. Ogni segue, come hai capito punta ad un VC di destinazione. Infatti ha una proprietà chiamata destinationViewController che ti permette d’accedere all’istanza del ViewController a cui punta.

Nel tuo caso, il destination ViewController è rappresentato dalla classe SecondViewController. Se ti ricordi avevi creato ad inizio tutorial una classe da associare al tuo VC nello storyboard. Quindi in un’altra delle tue applicazioni questo destination ViewController dovrà essere castato nel tipo di dato che utilizzi per gestire il VC di destinazione.

Se castato, classi, metodi e proprietà ti suonano come cose nuove, forse è il caso di partire da qualcosa di più semplice. Dai un’occhiata ai miei consigli per cominciare a creare applicazioni nel modo corretto.

Nel tuo esempio, utilizzerai il prepareForSegue e questa proprietà per settare il valore della var stringaDiPassaggio uguale al contenuto della TextField:

Quando l’utente cliccherà sul bottone Vai Avanti, questo è quello che succederà:

  1. Verrà invocato il metodo performSegue che attiva il Segue che hai creato su storyboard con Identifier showSecondVC
  2. Prima di arrivare al VC di destinazione, viene invocato il metodo prepare.
  3. All’interno del prepare, che può essere chiamato da qualsiasi segue del VC, viene utilizzato uno switch (se non ti ricordi cos’è vedi il corso gratuito sul linguaggio Swift) che attiva un determinato codice in base all’identifier (il segue) che è stato attivato.
    1. Dentro il case “showSecondVC” viene preso il VC di destinazione del Segue per poter inviargli le informazioni. Cioè il destination viene castato nel tipo tipo di dato che gestisce quel VC per poter accedere correttamente ai suoi attributi (la classe che hai utilizzato come Custom Class del ViewController che hai nello storyboard).
    2. Dato che il VC di destinazione non è ancora visualizzato, non puoi passare i valori alle Outlet che gestiscono la grafica. Pertanto si creano delle variabili d’appoggio nella classe di destinazione. I dati vengono passate, nel prepare, a queste proprietà.
  4. Infine, dopo il prepare, viene visualizzato il VC di destinazione.
  5. Se sono stati previsti passaggi di informazioni, nel viewDidLoad del destinatario si passano i valori dalle var d’appoggio agli elementi grafici.

L’ultimo passaggio della lista non è stato ancora eseguito. Infatti hai creato il prepare hai detto che invierai i valori alla stringaDiPassaggio ma non hai ancora modificato il SecondViewController per aggiornare i suoi elementi.

Vai nel SecondViewController e, nel viewDidLoad, passa la stringaDiPassaggio alla sua Label.

Unwind Segue in Swift. Passare delle informazioni ai ViewController precedenti

Quando vai avanti da un ViewController A ad uno B, in realtà quello che sta dietro non viene mai eliminato del tutto. Come quando cammini in un sentiero dove il percorso che hai già fatto dovresti sempre ricordartelo, allo stesso modo, per la navigazione tra i Controller, i VC già passati vengono mantenuti in memoria fin quando non si ritorna al punto di partenza.

Questo è anche il motivo per cui non si può creare un Segue che va verso dietro, cioè non puoi tracciare una linea da un VC B ad un VC A.

Come si fa dunque a creare un Unwind Segue?

Il procedimento è un po’ macchinoso ma se capito riuscirai ad implementarlo in maniera veloce nei tuoi progetti.

Tutto parte dal VC di ritorno cioè dal VC A in cui vuoi tornare indietro. Nel nostro esempio, il VC a cui vogliamo tornare e contemporaneamente trasportare dati è il ViewController di colore Verde. Il NavigationController già ci da un sistema per poter tornare indietro, quel bottone che ha messo in automatico nella ToBar di navigazione. Il problema è che non si può trasportare un’informazione utilizzando quel sistema.

La tecnica che ti spiegherò potrai applicarla in qualsiasi situazione. Quindi con o senza NavigationController potrai utilizzare l’Unwind Segue.

Nel VC in cui vuoi tornare indietro, nel tuo caso il verde, devi creare una particolare IBAction (cioè quella particolare funzione che risponde ad un evento dell’interfaccia) che come parametro della sua funzione ha un UIStoryboardSegue. Quindi, vai nel ViewController e aggiungi la seguente funzione:

Il nome della funzione puoi cambiarlo in quello che più ti aggrada. L’importante è che sia una IBAction e che abbia come parametro un UIStoryboardSegue come tipo di dato.

Adesso, vai nello storyboard e spostati sul ViewController Blu, cioè quello che farà partire l’UnwindSegue cioè il comando per tornare indietro.

Da qui, seleziona il ViewController e, come se volessi creare un Segue normale, trascina la freccia verso quel bottoncino in alto a destra a forma di simbolo d’uscita (chiamato Exit Event). Una volta fatto, si aprirà un menu in cui ti verrà chiesto di selezionare il metodo di unwind da richiamare. Dovresti vedere la funzione che hai scritto nel VC di destinazione (la famosa IBAction che ti ho fatto creare poc’anzi):

Unwind Segue in swift

Questa operazione crea un particolare segue chiamato di Unwind. Se non crei prima la IBAction nel VC di ritorno, questo menu non si aprirà mai. Cioè devi prima creare la IBAction di unwind e poi creare l’Unwind Segue.

Essendo anche questo un Segue, dovrà essere provvisto di un Identifier dato che potrai creare più segue di ritorno che partono dal seguente VC. In questo caso, però, non hai una freccia nello storyboard e per selezionare il Segue di Unwind dovrai utilizzare il Document Outline (cioè il pannello di sinistra che trovi dentro l’area di lavoro dello storyboard). Una volta selezionato, nell’Attributes Inspector potrai assegnargli un Identifier:

Unwind Segue Identifier in swift

Adesso, come un normalissimo Segue, sarai in grado di attivarlo utilizzando il metodo performSegue. Dove dovrà essere chiamato? Ovviamente nel VC blu cioè nel SecondViewController dato che vogliamo tornare al VC verde (che ti ricordo contiene la IBAction che gestirà questo particolare Segue).

Nella IBAction vaiIndietro del SecondViewController, aggiungi la chiamata all’unwind segue tramite performSegue:

Adesso, quando attiverai l’app e premerai sul bottone potrai tornare indietro utilizzando l’unwind segue. Una volta che il performSegue attiverà l’unwind, questo attiverà sempre il prepare (in questo caso possiamo evitare di inserirlo) e poi chiamerà la IBAction presente nel VC di destinazione. 

Sopra ti ho detto che non è necessario implementare il prepare quando si torna indietro. Allora dove pesco le informazioni da trasportare?

Ti ho fatto vedere che, nel processo di Unwind viene attivata la IBAction che hai creato nel VC di destinazione. Il suo parametro è sempre un UIStoryboardSegue, questo vuol dire che conterrà comunque le informazioni del VC sorgente e ovviamente destinatario.

Nel caso dell’Unwind, il destinatario è il VC verde cioè quello in cui è presente l’IBAction e la sorgente è il VC blu cioè quello da cui parte l’Unwind. Dato che noi vogliamo le informazioni inserite nel Blu e l’IBAction si trova nel destinatario, ci basterà prendere le informazioni dal source, che sostituisce il metodo sourceViewController, (sempre castato nel tipo di dato che lo gestisce) per poter aggiornare i suoi dati.

Cioè, nella IBAction di Unwind, accederai alle informazioni contenute nella sorgente (cioè chi ha chiamato il segue di unwind) e pescherai il testo contenuto nella sua TextField per poter aggiornare la Label del VC verde:

Considerazioni e Download del progetto

Ovviamente passare informazioni da View a View in Swift non si limita a semplici tipi di dato ma anche a più complessi come le immagini, le liste e tutto quello che è raffigurabile tramite oggetto.

Questo è solo un estratto di un procedimento più lungo e complesso che ho spiegato nel corso di sviluppo iOS. Negli altri tutorial troverai altri sistemi per passare informazioni e altri tipi di utilizzo o implementazione.

Dove andare da qui

Download del progetto finale

Se hai avuto problemi con il tuo progetto, qui sotto puoi scaricare quello fatto da me:

[sociallocker] DropBox download file [/sociallocker]

Buona programmazione!

Changelog

  • 27/10/2016 – Aggiunto il changelog. Modifica del tutorial e verifica compatibilità con Xcode 8.

Start typing and press Enter to search

Core Data in SwiftGuida all'interfaccia di Xcode. Come muovere i primi passi su Xcode.