In letzter Zeit habe ich viel damit experimentiert, Dinge in Swift anders zu machen. Ich bin immer noch auf der Suche nach bewährten Methoden und entdecke völlig neue Wege, Dinge zu tun. Ein Beispiel dafür ist die Übergabe von Objekten von einem View Controller an einen anderen durch einen Segue in einer einzigen Codezeile, die ich in diesem Beitrag behandeln werde.
Stellen Sie sich zwei View-Controller vor, einen BookViewController und einen AuthorViewController. Beide befinden sich im selben Storyboard und der BookViewController verfügt über eine Schaltfläche, die den AuthorViewController auf dem Navigationscontroller über einen Segue ansteuert. Um zu wissen, welchen Autor wir auf dem AuthorViewController anzeigen müssen, müssen wir ein Autorenobjekt vom BookViewController an den AuthorViewController übergeben. Der traditionelle Weg, dies zu tun, besteht darin, der Segue einen Bezeichner zu geben und dann das Objekt zu setzen:
[objc]
class BookViewController: UIViewController {
var book: Book!
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "ShowAuthor" {
let authorViewController = segue.destinationViewController as! AuthorViewController
authorViewController.author = book.author
}
}
}
class AuthorViewController: UIViewController {
var author: Author!
}
[/objc]
Und für den Fall, dass wir einen modalen Übergang verwenden, der einen AuthorViewController zeigt, der in einen Navigationscontroller eingebettet ist, wäre der Code etwas komplexer:
[objc]
if segue.identifier == "ShowAuthor" {
let authorViewController = (segue.destinationViewController as! UINavigationController).viewControllers[0] as! AuthorViewController
authorViewController.author = book.author
}
[/objc]
Lassen Sie uns nun sehen, wie wir eine Erweiterung zu UIStoryboardSegue hinzufügen können, die dies etwas einfacher macht und für beide Szenarien gleich funktioniert. Anstatt den Segue-Identifikator zu überprüfen, werden wir nur den Typ des Ziel-Viewcontrollers überprüfen. Wir gehen davon aus, dass aufgrund des Typs dasselbe Objekt weitergegeben wird, auch wenn es mehrere Segues gibt, die an diesen Typ gehen.
[objc]
extension UIStoryboardSegue {
func destinationViewControllerAs<T>(cl: T.Type) -> T? {
return destinationViewController as? T ?? (destinationViewController as? UINavigationController) as?.viewControllers[0] as? T
[/objc] }
}
Wir haben hier die Methode destinationViewControllerAs zu UIStoryboardSegue hinzugefügt, die überprüft, ob der destinationViewController vom generischen Typ T ist. Ist dies nicht der Fall, prüft sie, ob der destinationViewController ein Navigationscontroller ist und ob sein erster Viewcontroller vom Typ T ist. Wenn es einen von beiden findet, gibt es diese Instanz von T zurück. Da es auch Null sein kann, ist der Rückgabetyp ein optionales T.
Es ist jetzt unglaublich einfach, unser Author-Objekt an den AuthorViewController zu übergeben:
[objc]
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
segue.destinationViewControllerAs(AuthorViewController.self)?.author = book.author
}
[/objc]
Sie brauchen keine Bezeichner mehr zu prüfen und brauchen weniger Code. Ich behaupte nicht, dass dies der beste Weg ist oder dass er sogar besser ist als die herkömmliche Methode, Dinge zu tun. Aber es zeigt, dass Swift uns neue Möglichkeiten bietet und es sich lohnt, zu experimentieren, um die besten Methoden zu finden.
Der Quellcode der Beispiele und der Erweiterung ist auf GitHub verfügbar - lammertw/StoryboardSegueExtension.