Xebia Blog

Uno dei lati negativi dell’uso dei segues negli storyboard è che spesso hai ancora bisogno di scrivere codice per passare i dati dal view controller sorgente al view controller di destinazione. Il metodo prepareForSegue(_:sender:) è il posto giusto per farlo. A volte è necessario innescare manualmente un segue chiamando performSegueWithIdentifier(_:sender:), ed è lì che di solito si sa quali dati è necessario passare. Come possiamo evitare di aggiungere ulteriori variabili di stato nel nostro source view controller solo per il passaggio dei dati? Un semplice trucco è quello di utilizzare il parametro sender che entrambi i metodi hanno.

Aggiornamento:
Tenete a mente che questo è considerato un anti-pattern come commentato da alcuni lettori qui sotto, questo post ha lo scopo di esplorare le possibilità dei segues, il che non significa che dovete usarlo sempre. Usalo solo quando è appropriato o quando non ci sono altre opzioni disponibili.

Il parametro sender è normalmente usato dagli storyboard per indicare l’elemento UI che ha innescato la segue, per esempio un UIButton quando viene premuto o una UITableViewCell che attiva la segue selezionandola. Questo permette di determinare cosa ha innescato il segue in prepareForSegue:sender:, e sulla base di questo (e ovviamente dell’identificatore del segue) intraprendere alcune azioni e configurare il controller della vista di destinazione, o anche determinare che non dovrebbe eseguire affatto il segue restituendo false in shouldPerformSegueWithIdentifier(_:sender:).

Quando non è possibile innescare il segue da un elemento dell’UI nello Storyboard, è necessario utilizzare performSegueWithIdentifier(_:sender:) per innescarlo manualmente. Questo potrebbe accadere quando nessuna interazione diretta dell’utente dovrebbe innescare l’azione di qualche controllo che è stato creato nel codice. Forse si vuole eseguire qualche logica aggiuntiva quando si preme un pulsante e poi eseguire il segue. Qualunque sia la situazione, potete usare l’argomento sender a vostro vantaggio. Puoi passare qualsiasi cosa tu abbia bisogno in prepareForSegue(_:sender:) o shouldPerformSegueWithIdentifier(_:sender:).

Diamo un’occhiata ad alcuni esempi.

Screen Shot 2015-05-08 at 23.25.37

Qui abbiamo due view controller molto semplici. Il primo ha tre pulsanti per diversi colori. Quando si tocca uno dei pulsanti, il nome del colore selezionato sarà messo su un’etichetta e spingerà il secondo view controller. Il view controller spinto imposterà il suo colore di sfondo al colore rappresentato dal pulsante toccato. Per fare questo, abbiamo bisogno di passare un oggetto UIColor al controller della vista di destinazione.

Anche se questo potrebbe essere gestito creando 3 distinte sequenze dai pulsanti direttamente al controller della vista di destinazione, abbiamo scelto di gestire noi stessi il tocco del pulsante e di innescare la sequenza manualmente.

Potresti arrivare con qualcosa come il seguente codice per realizzare questo:

class ViewController: UIViewController {

@IBOutlet weak var label: UILabel!

var tappedColor: UIColor?

@IBAction func tappedRed(sender: AnyObject) {
label.text = “Tapped Red”
tappedColor = UIColor.redColor()
performSegueWithIdentifier(“ShowColor”, sender: sender)
}

@IBAction func tappedGreen(sender: AnyObject) {
label.text = “Tapped Green”
tappedColor = UIColor.greenColor()
performSegueWithIdentifier(“ShowColor”, sender: sender)
}

@IBAction func tappedBlue(sender: AnyObject) {
label.text = “Tapped Blue”
tappedColor = UIColor.blueColor()
performSegueWithIdentifier(“ShowColor”, sender: sender)
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == “ShowColor” {
if let colorViewController = segue.destinationViewController as? ColorViewController {
colorViewController.color = tappedColor
}
}
}

}

class ColorViewController: UIViewController {

var color: UIColor?

override func viewDidLoad() {
super.viewDidLoad()

view.backgroundColor = color
}

}

Abbiamo creato una variabile di stato chiamata tappedColor per tenere traccia del colore che deve essere passato. Viene impostata in ogni metodo d’azione prima di chiamare performSegueWithIdentifier(“ShowColor”, sender: sender) e poi letta di nuovo in prepareForSegue(_:sender:) in modo da poterla passare al view controller di destinazione.

I metodi d’azione avranno l’UIButtons tapped impostato come argomento sender, e poiché questo è l’elemento effettivo che ha iniziato l’azione, ha senso impostarlo come sender quando si esegue il segue. Questo è ciò che facciamo nel codice di cui sopra. Ma dato che non usiamo effettivamente il mittente quando prepariamo la sequenza, potremmo anche passare direttamente il colore. Ecco una nuova versione del ViewController che fa esattamente questo:

class ViewController: UIViewController {

@IBOutlet weak var label: UILabel!

@IBAction func tappedRed(sender: AnyObject) {
label.text = “Taped Red”
performSegueWithIdentifier(“ShowColor”, sender: UIColor.redColor())
}

@IBAction func tappedGreen(sender: AnyObject) {
label.text = “Tapped Green”
performSegueWithIdentifier(“ShowColor”, sender: UIColor.greenColor())
}

@IBAction func tappedBlue(sender: AnyObject) {
label.text = “Tapped Blue”
performSegueWithIdentifier(“ShowColor”, sender: UIColor.blueColor())
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == “ShowColor” {
if let colorViewController = segue.destinationViewController as? ColorViewController {
colorViewController.color = sender as? UIColor
}
}
}

}

Questo ci permette di sbarazzarci della nostra variabile extra tappedColor.

Può sembrare (e forse lo fa) un abuso del parametro sender, quindi usatelo con cura e solo dove appropriato. Siate consapevoli delle conseguenze; se qualche altro codice o qualche elemento in uno Storyboard innesca la stessa sequenza (cioè con lo stesso identificatore), allora il mittente potrebbe essere solo un elemento dell’interfaccia utente invece dell’oggetto che vi aspettavate, il che porterà a risultati inaspettati e forse anche a crash quando forzate il mittente a qualcosa che non è.

Puoi trovare il codice di esempio sotto forma di un progetto Xcode su https://github.com/lammertw/SegueColorSample.

Vuoi saperne di più su questo argomento?
Guarda i nostri servizi di consulenza, offerte di formazione e carriere qui sotto o contattaci a [email protected]

.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.