Xebia Blog

Einer der Nachteile der Verwendung von Segues in Storyboards ist, dass man oft noch Code schreiben muss, um Daten vom Quell-View Controller an den Ziel-View Controller weiterzugeben. Die prepareForSegue(_:sender:) Methode ist der richtige Ort um dies zu tun. Manchmal muss man einen Segue manuell auslösen, indem man performSegueWithIdentifier(_:sender:) aufruft, und dort weiß man normalerweise, welche Daten man weitergeben muss. Wie können wir es vermeiden, zusätzliche Zustandsvariablen in unserem Source-View-Controller nur für die Übergabe von Daten hinzuzufügen? Ein einfacher Trick ist die Verwendung des Absenderparameters, den beide Methoden haben.

Aktualisierung:
Bitte denken Sie daran, dass dies als Anti-Pattern angesehen wird, wie von einigen Lesern unten kommentiert, dieser Beitrag soll die Möglichkeiten von Segues erkunden, was nicht bedeutet, dass Sie es immer verwenden sollten. Verwenden Sie es nur, wenn es angemessen ist oder wenn keine andere Option zur Verfügung steht.

Der Absender-Parameter wird normalerweise von Storyboards verwendet, um das UI-Element anzugeben, das den Segue ausgelöst hat, z. B. ein UIButton, wenn er gedrückt wird, oder eine UITableViewCell, die den Segue auslöst, wenn sie ausgewählt wird. Dies ermöglicht es Ihnen, zu bestimmen, was den Segue in prepareForSegue:sender: ausgelöst hat, und basierend darauf (und natürlich dem Segue-Identifikator) einige Maßnahmen zu ergreifen und den Ziel-View-Controller zu konfigurieren oder sogar zu bestimmen, dass er den Segue überhaupt nicht ausführen soll, indem er false in shouldPerformSegueWithIdentifier(_:sender:) zurückgibt.

Wenn es nicht möglich ist, den Segue von einem UI-Element im Storyboard auszulösen, müssen Sie stattdessen performSegueWithIdentifier(_:sender:) verwenden, um ihn manuell auszulösen. Dies kann vorkommen, wenn keine direkte Benutzerinteraktion die Aktion eines Steuerelements auslösen soll, das im Code erstellt wurde. Vielleicht möchten Sie beim Drücken einer Schaltfläche eine zusätzliche Logik ausführen und danach den Segue ausführen. Wie auch immer die Situation aussieht, Sie können das Absenderargument zu Ihrem Vorteil nutzen. Sie können alles, was Sie benötigen, in prepareForSegue(_:sender:) oder shouldPerformSegueWithIdentifier(_:sender:) übergeben.

Schauen wir uns einige Beispiele an.

Screen Shot 2015-05-08 at 23.25.37

Hier haben wir zwei sehr einfache Viewcontroller. Der erste hat drei Schaltflächen für verschiedene Farben. Wenn man auf eine der Schaltflächen tippt, wird der Name der ausgewählten Farbe auf ein Etikett geschrieben und der zweite View-Controller wird gedrückt. Der gedrückte View-Controller setzt seine Hintergrundfarbe auf die Farbe, die durch die getippte Schaltfläche dargestellt wird. Um dies zu tun, müssen wir ein UIColor-Objekt an den Ziel-View-Controller übergeben.

Auch wenn dies durch die Erstellung von 3 verschiedenen Segues von den Buttons direkt zum Ziel-View-Controller gehandhabt werden könnte, haben wir uns entschieden, den Button-Tap selbst zu behandeln und die Segue manuell auszulösen.

Um dies zu bewerkstelligen, könnte man sich etwas wie den folgenden Code ausdenken:

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
}

}

Wir haben eine Zustandsvariable namens tappedColor erstellt, um die Farbe zu verfolgen, die weitergegeben werden muss. Sie wird in jeder der Action-Methoden vor dem Aufruf von performSegueWithIdentifier(„ShowColor“, sender: sender) gesetzt und dann in prepareForSegue(_:sender:) wieder ausgelesen, so dass wir sie an den Ziel-View-Controller weitergeben können.

Die Action-Methoden haben die getappten UIButtons als Absender-Argument, und da dies das eigentliche Element ist, das die Aktion initiiert hat, ist es sinnvoll, dies als Absender zu setzen, wenn die Segue ausgeführt wird. Das ist es, was wir im obigen Code tun. Aber da wir den Absender bei der Vorbereitung der Überblendung nicht wirklich verwenden, können wir die Farbe stattdessen auch direkt weitergeben. Hier ist eine neue Version des ViewControllers, die genau das tut:

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

}

Damit können wir unsere zusätzliche Variable tappedColor loswerden.

Es könnte den Anschein erwecken (und vielleicht tut es das auch), dass der Parameter sender missbraucht wird, also verwenden Sie ihn mit Vorsicht und nur dort, wo es angebracht ist. Seien Sie sich der Konsequenzen bewusst; wenn ein anderer Code oder ein Element in einem Storyboard denselben Segue auslöst (d.h. mit demselben Bezeichner), dann könnte der Absender einfach ein UI-Element statt des erwarteten Objekts sein, was zu unerwarteten Ergebnissen und vielleicht sogar zu Abstürzen führt, wenn Sie den Absender zu etwas zwingen, das er nicht ist.

Den Beispielcode in Form eines Xcode-Projekts finden Sie auf https://github.com/lammertw/SegueColorSample.

Möchten Sie mehr über dieses Thema erfahren?
Sehen Sie sich unsere Beratungsleistungen, Schulungsangebote und Karrieremöglichkeiten an oder kontaktieren Sie uns unter [email protected]

.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.