Xebia Blog

Un des inconvénients de l’utilisation des segues dans les storyboards est que vous devez souvent encore écrire du code pour transmettre les données du contrôleur de vue source au contrôleur de vue de destination. La méthode prepareForSegue(_:sender 🙂 est le bon endroit pour le faire. Parfois, vous devez déclencher manuellement une segue en appelant performSegueWithIdentifier(_:sender :), et c’est là que vous savez généralement quelles données vous devez transmettre. Comment éviter d’ajouter des variables d’état supplémentaires dans notre contrôleur de vue source uniquement pour transmettre des données ? Une astuce simple est d’utiliser le paramètre sender que les deux méthodes ont.

Mise à jour:
Veuillez garder à l’esprit que ceci est considéré comme un anti-pattern comme commenté par certains lecteurs ci-dessous, ce post est destiné à explorer les possibilités des segues, ce qui ne signifie pas que vous devez toujours l’utiliser. Ne l’utilisez que lorsque cela est approprié ou lorsqu’aucune autre option n’est disponible.

Le paramètre sender est normalement utilisé par les storyboards pour indiquer l’élément d’interface utilisateur qui a déclenché la segue, par exemple un UIButton lorsqu’il est pressé ou un UITableViewCell qui déclenche la segue en le sélectionnant. Cela vous permet de déterminer ce qui a déclenché la segue dans prepareForSegue:sender :, et en fonction de cela (et bien sûr de l’identifiant de la segue) de prendre certaines actions et de configurer le contrôleur de vue de destination, ou même de déterminer qu’il ne doit pas du tout exécuter la segue en retournant false dans shouldPerformSegueWithIdentifier(_:sender :).

Quand il n’est pas possible de déclencher la segue à partir d’un élément d’interface utilisateur dans le Storyboard, vous devez utiliser performSegueWithIdentifier(_:sender 🙂 à la place pour la déclencher manuellement. Cela peut se produire lorsqu’aucune interaction directe de l’utilisateur ne doit déclencher l’action d’un contrôle qui a été créé en code. Vous souhaitez peut-être exécuter une logique supplémentaire en appuyant sur un bouton, puis exécuter la séquence. Quelle que soit la situation, vous pouvez utiliser l’argument sender à votre avantage. Vous pouvez passer tout ce dont vous pouvez avoir besoin dans prepareForSegue(_:sender 🙂 ou shouldPerformSegueWithIdentifier(_:sender :).

Regardons quelques exemples.

Capture d'écran 2015-05-08 à 23.25.37

Nous avons ici deux contrôleurs de vue très simples. Le premier a trois boutons pour différentes couleurs. En tapant sur l’un des boutons, le nom de la couleur sélectionnée sera mis sur une étiquette et il poussera le deuxième contrôleur de vue. Le contrôleur de vue poussé définira sa couleur de fond à la couleur représentée par le bouton tapé. Pour ce faire, nous devons transmettre un objet UIColor au contrôleur de vue cible.

Même si cela pourrait être géré en créant 3 séquences distinctes des boutons directement vers le contrôleur de vue de destination, nous avons choisi de gérer le tapotement du bouton nous-mêmes et le déclenchement de la séquence manuellement.

Vous pourriez arriver à quelque chose comme le code suivant pour accomplir cela:

classe 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
}

}

Nous avons créé une variable d’état appelée tappedColor pour garder la trace de la couleur qui doit être transmise. Elle est définie dans chacune des méthodes d’action avant d’appeler performSegueWithIdentifier(« ShowColor », sender : sender) et ensuite relue dans prepareForSegue(_:sender 🙂 afin que nous puissions la transmettre au contrôleur de vue de destination.

Les méthodes d’action auront les UIButtons tapés définis comme argument d’expéditeur, et puisque c’est l’élément réel qui a initié l’action, il est logique de le définir comme expéditeur lors de l’exécution du segue. C’est donc ce que nous faisons dans le code ci-dessus. Mais puisque nous n’utilisons pas réellement l’expéditeur lors de la préparation de la transition, nous pouvons tout aussi bien transmettre la couleur directement à la place. Voici une nouvelle version du ViewController qui fait exactement cela:

class ViewController : UIViewController {

@IBOutlet weak var label : UILabel!

@IBAction func tappedRed(sender : AnyObject) {
label.text = « Tapped 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
}
}
}

}

Cela nous permet de nous débarrasser de notre variable supplémentaire tappedColor.

Il pourrait sembler (et peut-être que c’est le cas) abuser du paramètre sender cependant, donc utilisez-le avec précaution et seulement lorsque cela est approprié. Soyez conscient des conséquences ; si un autre code ou un élément dans un Storyboard déclenche la même segue (c’est-à-dire avec le même identifiant), alors l’expéditeur pourrait juste être un élément de l’interface utilisateur au lieu de l’objet que vous attendiez, ce qui conduira à des résultats inattendus et peut-être même à des crashs lorsque vous forcez le sender à quelque chose qu’il n’est pas.

Vous pouvez trouver l’exemple de code sous la forme d’un projet Xcode sur https://github.com/lammertw/SegueColorSample.

Vous voulez en savoir plus sur ce sujet ?
Regardez nos services de conseil, nos offres de formation et nos carrières ci-dessous ou contactez-nous à [email protected]

.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.