The Missing Manual
for Swift Development
The Guide I Wish I Had When I Started Out
Join 20,000+ Entwickler, die etwas über Swift-Entwicklung lernen
Laden Sie Ihr kostenloses Exemplar herunter
Das Fotos-Projekt verwendet ausschließlich Storyboards, um View-Controller zu entwerfen und zu erstellen. In dieser Folge zeige ich Ihnen, dass das Koordinatormuster nicht auf Storyboards beschränkt ist. Sie können das Koordinatormuster auch verwenden, wenn Sie XIB-Dateien gegenüber Storyboards bevorzugen. Wenn Sie weder das eine noch das andere bevorzugen, dann ist das auch möglich. Es spielt keine Rolle, wie Sie die Viewcontroller Ihres Projekts entwerfen und erstellen.
Starterprojekt
Das Starterprojekt dieser Folge ist funktionell identisch mit dem fertigen Projekt der vorherigen Folge. Es gibt jedoch ein paar Unterschiede, auf die ich hinweisen möchte. Die Klasse TermsViewController
entspricht nicht mehr dem Storyboardable
-Protokoll und hat jetzt drei Unterklassen, TermsViewControllerStoryboard
, TermsViewControllerXIB
und TermsViewControllerCode
.
Die Klasse TermsViewControllerStoryboard
ist identisch mit der Klasse TermsViewController
der vorherigen Folge. Die Benutzerschnittstelle der Klasse TermsViewControllerStoryboard
ist in Main.storyboard definiert. Wir können eine Instanz der Klasse instanziieren, indem wir die instantiate()
-Methode des Storyboardable
-Protokolls aufrufen.
Die Benutzeroberfläche der TermsViewControllerXIB
-Klasse ist in TermsViewControllerXIB.xib definiert. Die Klasse TermsViewControllerXIB
definiert eine statische, variable Eigenschaft, nibName
, um die Verwendung von String-Literalen zu vermeiden. Dies ähnelt der Eigenschaft storyboardIdentifier
, die in Storyboardable.swift definiert ist.
Wie der Name schon sagt, hat die Klasse TermsViewControllerCode
keinen Link zu einem Storyboard oder einer XIB-Datei. Die Benutzeroberfläche wird im Code erstellt. Dies führt natürlich zu einer größeren Menge an Code. Werfen wir einen Blick auf jeden dieser View-Controller und untersuchen, wie sie sich in das Coordinator-Pattern einfügen.
Storyboards
Storyboards gibt es schon seit einigen Jahren und Apple ermutigt Entwickler, sie zu verwenden. Ich verwende Storyboards in den meisten Projekten, an denen ich arbeite. Xcode erstellt automatisch ein Storyboard, wenn Sie ein neues Projekt anlegen, aber ich empfehle dringend, mehrere kleinere Storyboards anstelle eines großen Storyboards zu verwenden. Durch die Verwendung mehrerer kleinerer Storyboards lassen sich Merge-Konflikte leichter vermeiden, und die Arbeit mit kleineren Storyboards ist schneller und weniger komplex.
Seguen sind eine wichtige Funktion von Storyboards, aber ich verwende sie nie in Kombination mit dem Coordinator-Muster. Es ist zwar möglich, Segues in Kombination mit dem Coordinator-Pattern zu verwenden, aber ein Segue bindet den View-Controller in den Anwendungsfluss ein, und das ist etwas, das wir vermeiden wollen. Denken Sie daran, dass die Koordinatoren des Projekts den Anwendungsfluss steuern. Ein View-Controller muss nichts über den Anwendungsfluss wissen und er muss auch nichts über andere View-Controller wissen.
Auch ohne Segues haben Storyboards ihren Wert. Ich teile mittlere bis große Projekte immer in Module auf. Jedes Modul hat ein Storyboard, das die Viewcontroller des Moduls enthält.
Öffnen Sie TermsCoordinator.swift und navigieren Sie zu der Methode showTerms()
. Die Implementierung ist identisch mit der des fertigen Projekts aus der vorherigen Episode. Der einzige Unterschied ist der Name der View-Controller-Klasse. Der Termkoordinator instanziiert die Klasse TermsViewControllerStoryboard
anstelle der Klasse TermsViewController
.
// MARK: - Helper Methodsprivate func showTerms() { // Initialize Terms View Controller let termsViewController = TermsViewControllerStoryboard.instantiate() // Install Handlers termsViewController.didCancel = { in self?.finish() } // Present Terms View Controller presentingViewController.present(termsViewController, animated: true)}
XIBs
XIB-Dateien gibt es schon seit den frühen Tagen der Cocoa-Entwicklung. Im Vergleich zu Storyboards fehlen ihnen ein paar Funktionen, aber sie haben immer noch ihren Wert. Ich verwende XIBs in erster Linie für wiederverwendbare Komponenten, wie z. B. Zellen in der Tabellenansicht und in der Auflistungsansicht.
Öffnen Sie TermsViewControllerXIB.xib. Die Benutzeroberfläche der Klasse TermsViewControllerXIB
ist identisch mit der der Klasse TermsViewControllerStoryboard
in Main.storyboard. Öffnen Sie TermsCoordinator.swift und rufen Sie die Methode showTerms()
erneut auf. Um eine Instanz der Klasse TermsViewControllerXIB
zu erstellen, rufen wir den Initialisierer init(nibName:bundle:)
auf und übergeben den Namen der XIB-Datei und einen Verweis auf das Bundle, das die XIB-Datei enthält.
// MARK: - Helper Methodsprivate func showTerms() { // Initialize Terms View Controller let termsViewController = TermsViewControllerXIB(nibName: TermsViewControllerXIB.nibName, bundle: .main) // Install Handlers termsViewController.didCancel = { in self?.finish() } // Present Terms View Controller presentingViewController.present(termsViewController, animated: true)}
Code
Es ist auch möglich, die Benutzeroberfläche der View-Controller des Projekts im Code zu erstellen. Wenn Sie keine Storyboards oder XIB-Dateien mögen, dann ist dies die einzige Möglichkeit. Ich habe diese Option seit der Einführung von Storyboards nicht mehr sehr oft verwendet, aber sie kann von Zeit zu Zeit nützlich sein.
Das Erstellen und Initialisieren eines View-Controllers in Code ist nützlich, wenn dieser View-Controller eine komplexe oder dynamische Benutzeroberfläche hat. Das Erstellen und Initialisieren von View-Controllern im Code hat einen weiteren überzeugenden Vorteil. Es ermöglicht die Initialisierungsinjektion, eine Form der Dependency Injection. Ich bespreche Dependency Injection in der nächsten Folge.
Um eine Instanz der Klasse TermsViewControllerCode
zu erstellen, rufen wir den init()
Initializer auf. Das ist gleichbedeutend mit dem Aufruf des init(nibName:bundle:)
-Initialisierers und der Übergabe von nil
für beide Argumente.
// MARK: - Helper Methodsprivate func showTerms() { // Initialize Terms View Controller let termsViewController = TermsViewControllerCode() // Install Handlers termsViewController.didCancel = { in self?.finish() } // Present Terms View Controller presentingViewController.present(termsViewController, animated: true)}
Wie geht es weiter?
Das Koordinatormuster ist ein flexibles Muster. Es spielt keine Rolle, ob Sie Storyboards, XIB-Dateien oder beides verwenden. Sie können Segues verwenden, aber denken Sie daran, dass Sie damit gegen ein Grundprinzip des Coordinator Patterns verstoßen. Ein View-Controller muss nichts über den Ablauf der Anwendung wissen und er sollte auch nichts über andere View-Controller wissen.