
Apple hat Storyboards erstellt, damit Entwickler die Bildschirme von iOS-Anwendungen und die Beziehungen zwischen ihnen visualisieren können. Nicht jeder mochte dieses Tool und das aus gutem Grund. Ich habe viele Artikel getroffen, in denen Storyboards kritisiert wurden, aber ich habe keine detaillierte und unvoreingenommene Analyse aller Vor- und Nachteile unter Berücksichtigung von Best Practices gefunden. Am Ende habe ich beschlossen, einen solchen Artikel selbst zu schreiben.
Ich werde versuchen, die Nachteile und Vorteile der Verwendung von Storyboards im Detail zu analysieren. Nachdem Sie sie gewogen haben, können Sie eine aussagekräftige Entscheidung treffen, ob sie im Projekt benötigt werden oder nicht. Diese Entscheidung muss nicht radikal sein. Wenn Storyboards in bestimmten Situationen Probleme verursachen, ist ihre Verwendung in anderen gerechtfertigt: Sie hilft, Aufgaben effektiv zu lösen und einfachen, leicht zu wartenden Code zu schreiben.
Beginnen wir mit den Mängeln und analysieren, ob alle noch relevant sind.
Nachteile
1. Storyboards haben Schwierigkeiten, Konflikte beim Zusammenführen von Änderungen zu verwalten
Storyboard ist eine XML-Datei. Es ist weniger lesbar als Code, daher ist es schwieriger, Konflikte darin zu lösen. Diese Komplexität hängt aber auch davon ab, wie wir mit dem Storyboard arbeiten. Sie können Ihre Aufgabe erheblich vereinfachen, wenn Sie die folgenden Regeln befolgen:
- Platzieren Sie nicht die gesamte Benutzeroberfläche in einem einzigen Storyboard, sondern teilen Sie sie in mehrere kleinere auf. Auf diese Weise können Sie die Arbeit an Storyboards ohne das Risiko von Konflikten auf Entwickler verteilen und im Falle ihrer Unvermeidlichkeit die Lösung vereinfachen.
 
- Wenn Sie dieselbe Ansicht an mehreren Stellen verwenden müssen, wählen Sie sie in einer separaten Unterklasse mit einer eigenen Xib-Datei aus.
 
- Machen Sie häufiger Commits, da es viel einfacher ist, mit Änderungen in kleinen Stücken zu arbeiten.
 
Die Verwendung mehrerer Storyboards anstelle von einem macht es uns unmöglich, die gesamte Karte der Anwendung in einer Datei zu sehen. Aber oft ist dies nicht notwendig - nur der spezifische Teil, an dem wir gerade arbeiten, reicht aus.
2. Storyboards verhindern die Wiederverwendung von Code
Wenn wir im Projekt nur Storyboards ohne Xibs verwenden, treten mit Sicherheit Probleme auf. Allerdings sind Xibs meiner Meinung nach notwendige Elemente bei der Arbeit mit Storyboards. Dank ihnen können Sie problemlos wiederverwendbare Ansichten erstellen, mit denen Sie auch bequem im Code arbeiten können.
Erstellen Sie zunächst die Basis- 
XibView Klasse, die für das Rendern der in Xib erstellten 
UIView im Storyboard verantwortlich ist:
 @IBDesignable class XibView: UIView { var contentView: UIView? } 
XibView lädt das 
UIView von Xib in das 
contentView und fügt es als Unteransicht hinzu. Wir machen das in der 
setup() Methode:
 private func setup() { guard let view = loadViewFromNib() else { return } view.frame = bounds view.autoresizingMask = [.flexibleWidth, .flexibleHeight] addSubview(view) contentView = view } 
Die 
loadViewFromNib() -Methode sieht folgendermaßen aus:
 private func loadViewFromNib() -> UIView? { let nibName = String(describing: type(of: self)) let nib = UINib(nibName: nibName, bundle: Bundle(for: XibView.self)) return nib.instantiate(withOwner: self, options: nil).first as? UIView } 
Die 
setup() -Methode sollte in Initialisierern aufgerufen werden:
 override init(frame: CGRect) { super.init(frame: frame) setup() } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) setup() } 
Die 
XibView Klasse 
XibView bereit. Wiederverwendete Ansichten, deren Erscheinungsbild in einer Xib-Datei gerendert wird, werden von 
XibView geerbt:
 final class RedView: XibView { } 

Wenn Sie dem Storyboard jetzt eine neue 
UIView hinzufügen und deren Klasse auf 
RedView , wird alles erfolgreich angezeigt:

Das Erstellen einer Instanz von 
RedView im Code erfolgt wie 
RedView :
 let redView = RedView() 
Ein weiteres nützliches Detail, das nicht jeder kennen kann, ist die Möglichkeit, dem Verzeichnis 
.xcassets Farben 
hinzuzufügen . Auf diese Weise können Sie sie global in allen Storyboards und Xibs ändern, in denen sie verwendet werden.
Um Farbe hinzuzufügen, klicken Sie unten links auf „+“ und wählen Sie „Neues Farbset“:

Geben Sie den gewünschten Namen und die gewünschte Farbe an:

Die erstellte Farbe wird im Abschnitt "Benannte Farben" angezeigt:

Darüber hinaus kann es im Code erhalten werden:
 innerView.backgroundColor = UIColor(named: "BackgroundColor") 
3. Sie können keine benutzerdefinierten Initialisierer für in Storyboard erstellte UIViewControllers
Im Fall des Storyboards können wir keine Abhängigkeiten in den Initialisierern der 
UIViewControllers . Normalerweise sieht es so aus:
 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { guard segue.identifier == "detail", let detailVC = segue.destination as? DetailViewController else { return } let object = Object() detailVC.object = object } 
Dieser Code kann besser mit einer Art Konstante erstellt werden, um Bezeichner oder Tools wie 
SwiftGen und 
R.swift darzustellen , oder vielleicht sogar 
Perform . Aber auf diese Weise werden wir nur String-Literale los und fügen syntaktischen Zucker hinzu und lösen nicht die auftretenden Probleme:
- Woher weiß ich, wie der DetailViewControllerim obigen Beispiel konfiguriertDetailViewController? Wenn Sie neu im Projekt sind und nicht über dieses Wissen verfügen, müssen Sie eine Datei mit einer Beschreibung dieses Controllers öffnen und studieren.
 
- Die DetailViewControllerEigenschaftenDetailViewControllernach der Initialisierung festgelegt.DetailViewControllerbedeutet, dass sie optional sein müssen. Es ist erforderlich, Fälle zu behandeln, in denen eine Eigenschaft gleichnil, da die Anwendung sonst im ungünstigsten Moment abstürzen kann. Sie können Eigenschaften als implizit erweitert optional markieren (var object: Object!), Aber das Wesentliche ändert sich nicht.
 
- Eigenschaften müssen als varmarkiert sein, nichtlet. Eine Situation ist also möglich, wenn jemand von außerhalb sie ändern möchte.DetailViewControllersollte mit solchen Situationen umgehen.
 
Eine Lösung wird in 
diesem Artikel beschrieben .
4. Wenn das Storyboard wächst, wird die Navigation schwieriger
Wie bereits erwähnt, müssen Sie nicht alles in ein Storyboard einfügen. Es ist besser, es in mehrere kleinere zu unterteilen. Mit dem Aufkommen der 
Storyboard-Referenz ist es sehr einfach geworden.
Fügen Sie die Storyboard-Referenz aus der Objektbibliothek zum Storyboard hinzu:

Die erforderlichen Feldwerte werden im 
Attributinspektor festgelegt. Dies ist der Name der Storyboard-Datei und gegebenenfalls die 
referenzierte ID , die der 
Storyboard-ID des gewünschten Bildschirms entspricht. Standardmäßig wird der 
Initial View Controller geladen:

Wenn Sie im Feld Storyboard einen ungültigen Namen angeben oder auf eine nicht vorhandene Storyboard-ID verweisen, werden Sie bei der Kompilierung von Xcode darauf hingewiesen.
5. Xcode wird beim Laden von Storyboards langsamer
Wenn das Storyboard eine große Anzahl von Bildschirmen mit zahlreichen Einschränkungen enthält, dauert das Laden wirklich einige Zeit. Andererseits ist es besser, das große Storyboard in kleinere aufzuteilen. Separat werden sie viel schneller geladen und es wird bequemer, mit ihnen zu arbeiten.
6. Storyboards sind zerbrechlich. Ein Fehler kann dazu führen, dass die Anwendung zur Laufzeit abstürzt
Die Hauptschwächen:
- Fehler in den UITableViewCellundUICollectionViewCell.
 
- Fehler in den Segmentkennungen.
 
- Verwenden einer Unterklasse von UIView, die nicht mehr vorhanden ist.
 
- Synchronisation von IBActionsundIBOutletsmit Code.
 
All dies und einige andere Probleme können zur Laufzeit zum Absturz der Anwendung führen, was bedeutet, dass solche Fehler wahrscheinlich in den Release-Build fallen. Wenn wir beispielsweise Zellkennungen oder Segmente im Storyboard festlegen, sollten diese überall dort, wo sie verwendet werden, in den Code kopiert werden. Durch Ändern des Bezeichners an einer Stelle muss er an allen anderen Stellen geändert werden. Es besteht die Möglichkeit, dass Sie es einfach vergessen oder einen Tippfehler machen, aber nur während der Ausführung der Anwendung etwas über den Fehler erfahren.
Sie können die Fehlerwahrscheinlichkeit verringern, indem Sie Zeichenfolgenliterale in Ihrem Code entfernen. Zu diesem 
UICollectionViewCell können den Bezeichnern 
UITableViewCell und 
UICollectionViewCell die Namen der 
UICollectionViewCell selbst zugewiesen werden. Beispielsweise ist der Bezeichner 
ItemTableViewCell die Zeichenfolge „ItemTableViewCell“. Im Code erhalten wir die Zelle wie folgt:
 let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: ItemTableViewCell.self)) as! ItemTableViewCell 
Sie können der 
UITableView die entsprechende generische Funktion 
UITableView :
 extension UITableView { open func dequeueReusableCell<T>() -> T where T: UITableViewCell { return dequeueReusableCell(withIdentifier: String(describing: T.self)) as! T } } 
Und dann wird es einfacher, die Zelle zu bekommen:
 let cell: ItemTableViewCell = tableView.dequeueReusableCell() 
Wenn Sie plötzlich vergessen, den Wert der Zellenkennung im Storyboard anzugeben, zeigt Xcode eine Warnung an, sodass Sie diese nicht ignorieren sollten.
Für Segues-IDs können Sie Aufzählungen verwenden. Lassen Sie uns ein spezielles Protokoll erstellen:
 protocol SegueHandler { associatedtype SegueIdentifier: RawRepresentable } 
UIViewController , der dieses Protokoll unterstützt, muss einen verschachtelten Typ mit demselben Namen definieren. Es werden alle 
UIViewController , die dieser 
UIViewController kann:
 extension StartViewController: SegueHandler { enum SegueIdentifier: String { case signIn, signUp } } 
Darüber hinaus definieren 
SegueHandler in der 
SegueHandler Protokollerweiterung zwei Funktionen: Eine akzeptiert ein 
UIStoryboardSegue und gibt den entsprechenden 
SegueIdentifier Wert zurück, und die andere ruft einfach 
performSegue und nimmt die 
SegueIdentifier Eingabe:
 extension SegueHandler where Self: UIViewController, SegueIdentifier.RawValue == String { func performSegue(withIdentifier segueIdentifier: SegueIdentifier, sender: AnyObject?) { performSegue(withIdentifier: segueIdentifier.rawValue, sender: sender) } func segueIdentifier(for segue: UIStoryboardSegue) -> SegueIdentifier { guard let identifier = segue.identifier, let identifierCase = SegueIdentifier(rawValue: identifier) else { fatalError("Invalid segue identifier \(String(describing: segue.identifier)).") } return identifierCase } } 
Und jetzt können Sie in einem 
UIViewController , der das neue Protokoll unterstützt, wie folgt mit 
prepare(for:sender:) :
 extension StartViewController: SegueHandler { enum SegueIdentifier: String { case signIn, signUp } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { switch segueIdentifier(for: segue) { case .signIn: print("signIn") case .signUp: print("signUp") } } } 
Und laufen Sie wie folgt:
 performSegue(withIdentifier: .signIn, sender: nil) 
Wenn Sie dem 
SegueIdentifier einen neuen Bezeichner 
SegueIdentifier , wird Xcode ihn mit Sicherheit zwingen, ihn in 
switch/case .
Eine andere Möglichkeit, Zeichenfolgenliterale wie Bezeichner-Segues und andere zu 
entfernen, ist die Verwendung von Tools zur Codegenerierung wie 
R.swift .
7. Storyboards sind weniger flexibel als Code.
Ja, das ist wahr. Wenn die Aufgabe darin besteht, einen komplexen Bildschirm mit Animationen und Effekten zu erstellen, die das Storyboard nicht verarbeiten kann, müssen Sie den Code verwenden!
8. In Storyboards kann der Typ spezieller UIViewControllers nicht UIViewControllers
Wenn Sie beispielsweise den Typ von 
UITableViewController in 
UICollectionViewController UITableViewController UICollectionViewController , müssen Sie das Objekt löschen, ein neues mit einem anderen Typ hinzufügen und es neu konfigurieren. Obwohl dies nicht häufig vorkommt, ist es erwähnenswert, dass solche Änderungen im Code schneller vorgenommen werden.
9. Storyboards fügen dem Projekt zwei zusätzliche Abhängigkeiten hinzu. Sie können Fehler enthalten, die der Entwickler nicht beheben kann.
Dies ist Interface Builder und der Storyboards-Parser. Solche Fälle sind selten und können oft durch andere Lösungen umgangen werden.
10. Anspruchsvolle Codeüberprüfung
Beachten Sie, dass die Codeüberprüfung nicht wirklich eine Fehlersuche ist. Ja, sie werden beim Anzeigen des Codes gefunden, aber das Hauptziel besteht darin, Schwachstellen zu identifizieren, die auf lange Sicht zu Problemen führen können. Bei Storyboards ist dies in erster Linie die Arbeit von 
Auto Layout . Es sollte keine 
mehrdeutigen und 
verlegten geben . Um sie zu finden, verwenden Sie einfach die Suche im Storyboard-XML nach den Zeilen "mehrdeutig =" JA "" und "falsch platziert =" JA "" oder öffnen Sie einfach das Storyboard im Interface Builder und suchen Sie nach roten und gelben Punkten:

Dies reicht jedoch möglicherweise nicht aus. Konflikte zwischen Einschränkungen können auch während der Ausführung der Anwendung erkannt werden. Wenn eine ähnliche Situation auftritt, werden Informationen dazu in der Konsole angezeigt. Solche Fälle sind keine Seltenheit, daher sollte auch ihre Suche ernst genommen werden.
Alles andere - die Anpassung der Position und Größe der Elemente an das Design, die korrekte Bindung von 
IBOutlets und 
IBActions - dient nicht der 
IBOutlets .
Darüber hinaus ist es wichtig, häufiger Commits durchzuführen, damit der Prüfer die Änderungen in kleinen Teilen leichter sehen kann. Er wird besser in der Lage sein, in die Details einzutauchen, ohne etwas zu verpassen. Dies wirkt sich wiederum positiv auf die Qualität der Codeüberprüfung aus.
Zusammenfassung
In der Liste der Storyboard-Fehler habe ich 4 Elemente hinterlassen (in absteigender Reihenfolge ihres Werts):
- Storyboards haben Schwierigkeiten, Konflikte beim Zusammenführen von Änderungen zu verwalten.
 
- Storyboards sind weniger flexibel als Code.
 
- Storyboards sind zerbrechlich, ein Fehler kann zur Laufzeit zu einem Absturz führen.
 
- Sie können keine benutzerdefinierten Initialisierer für UIViewControllersdie im Storyboard erstellt wurden.
 
Die Vorteile
1. Visualisierung der Benutzeroberfläche und Einschränkungen
Selbst wenn Sie ein Anfänger sind und gerade ein unbekanntes Projekt gestartet haben, können Sie leicht den Einstiegspunkt in die Anwendung finden und herausfinden, wie Sie von dort aus zum gewünschten Bildschirm gelangen. Sie wissen, wie die einzelnen Schaltflächen, Beschriftungen oder Textfelder aussehen, welche Position sie einnehmen, wie sich Einschränkungen auf sie auswirken und wie sie mit anderen Elementen interagieren. Mit wenigen Klicks können Sie ganz einfach ein neues 
UIView erstellen und dessen Erscheinungsbild und Verhalten anpassen. Mit dem automatischen Layout können wir natürlich mit 
UIView , als ob wir gesagt hätten: "Diese Schaltfläche sollte sich links von diesem Etikett befinden und dieselbe Höhe haben." Diese Benutzeroberfläche ist intuitiv und effektiv. Sie können versuchen, Beispiele zu nennen, bei denen gut geschriebener Code beim Erstellen einiger UI-Elemente mehr Zeit spart, aber global ändert sich daran nicht viel. Storyboard macht seinen Job gut.
Beachten Sie separat das automatische Layout. Dies ist ein sehr leistungsfähiges und nützliches Tool, ohne das es schwierig wäre, eine Anwendung zu erstellen, die all die vielen verschiedenen Bildschirmgrößen unterstützt. Mit Interface Builder können Sie das Ergebnis der Arbeit mit Auto Layout anzeigen, ohne die Anwendung zu starten. Wenn einige Einschränkungen nicht in das allgemeine Schema passen, werden Sie von Xcode sofort gewarnt. Natürlich gibt es Fälle, in denen Interface Builder nicht in der Lage ist, das erforderliche Verhalten einer sehr dynamischen und komplexen Schnittstelle bereitzustellen, und Sie sich dann auf den Code verlassen müssen. Aber auch in solchen Situationen können Sie das meiste in Interface Builder tun und es mit nur ein paar Codezeilen ergänzen.
Schauen wir uns einige Beispiele an, die die nützlichen Funktionen von Interface Builder demonstrieren.
Dynamische Tabellen basierend auf UIStackView
Erstellen Sie einen neuen 
UIViewController und fügen Sie einen 
UIScrollView Vollbildmodus hinzu:

UIScrollView in 
UIScrollView eine vertikale 
UIStackView , 
UIStackView sie an den Kanten ein und stellen Sie die Höhe und Breite auf 
UIScrollView . Weisen Sie in dieser Höhe 
Priorität = Niedrig (250) zu :

Erstellen Sie als Nächstes alle erforderlichen Zellen und fügen Sie sie der 
UIStackView . Vielleicht ist es gewöhnliches 
UIView in einer einzigen Kopie oder 
UIView , für das wir unsere eigene Xib-Datei erstellt haben. In jedem Fall befindet sich die gesamte Benutzeroberfläche dieses Bildschirms im Storyboard. Dank des korrekt konfigurierten automatischen Layouts funktioniert das Scrollen einwandfrei und passt sich dem Inhalt an:

Wir können Zellen auch dazu bringen, sich an die Größe ihres Inhalts anzupassen. Fügen 
UILabel jeder Zelle 
UILabel und binden Sie sie an die Kanten:

Es ist bereits klar, wie dies alles zur Laufzeit aussehen wird. Sie können den Zellen beliebige Aktionen hinzufügen, z. B. zu einem anderen Bildschirm wechseln. Und das alles ohne eine einzige Codezeile.
Wenn Sie für eine 
UIView in einer 
UIStackView hidden = true UIStackView , wird diese nicht nur 
UIStackView , sondern nimmt auch keinen Speicherplatz ein. 
UIStackView berechnet seine Größen automatisch neu:

Selbstleimende Zellen
Setzen Sie im 
Größeninspektor der Tabelle die 
Zeilenhöhe = Automatisch und 
Schätzen auf einen Durchschnittswert:

Damit dies funktioniert, müssen Einschränkungen in den Zellen selbst korrekt konfiguriert sein und eine genaue Berechnung der Zellenhöhe basierend auf dem Inhalt zur Laufzeit ermöglichen. Wenn nicht klar ist, worum es geht, finden Sie in der 
offiziellen Dokumentation eine sehr gute Erklärung.
Als Ergebnis sehen wir beim Starten der Anwendung, dass alles korrekt angezeigt wird:

Selbstgrößen-Tabelle
Sie müssen dieses Tabellenverhalten implementieren:

Wie erreicht man eine ähnliche dynamische Höhenänderung? Im Gegensatz zu 
UILabel , 
UIButton und anderen Unterklassen von 
UIView ist die Verwendung einer Tabelle etwas schwieriger, da die Größe des 
intrinsischen Inhalts nicht von der Größe der darin enthaltenen Zellen abhängt. Sie kann ihre Größe nicht anhand des Inhalts berechnen, aber es besteht die Möglichkeit, ihr dabei zu helfen.
Beachten Sie, dass sich die Höhe der Tabelle irgendwann im Video nicht mehr ändert und einen bestimmten Maximalwert erreicht. Dies kann erreicht werden, indem die Tabellenhöhenbeschränkung mit dem Wert 
Relation = Less Than Or Equal festgelegt wird :

Zu diesem Zeitpunkt weiß der Interface Builder noch nicht, wie hoch die Tabelle sein wird, er kennt nur den Maximalwert von 200 (aus der Höhenbeschränkung). Wie bereits erwähnt, entspricht die intrinsische Inhaltsgröße nicht dem Inhalt der Tabelle. Wir haben jedoch die Möglichkeit, den Platzhalter im Feld 
Eigengröße festzulegen :

Dieser Wert ist nur gültig, wenn Sie mit Interface Builder arbeiten. Natürlich muss die intrinsische Inhaltsgröße zur Laufzeit nicht diesem Wert entsprechen. Wir haben Interface Builder gerade gesagt, dass alles unter Kontrolle ist.
Erstellen Sie als Nächstes eine neue Unterklasse der 
CustomTableView Tabelle:
 final class CustomTableView: UITableView { override var contentSize: CGSize { didSet { invalidateIntrinsicContentSize() } } override var intrinsicContentSize: CGSize { return contentSize } } 
Einer dieser Fälle, in denen der Code erforderlich ist. Hier rufen wir 
contentSize invalidateIntrinsicContentSize wenn sich die 
contentSize der Tabelle ändert. Dadurch kann das System die neue intrinsische Inhaltsgröße akzeptieren. Es gibt wiederum 
contentSize und zwingt die Tabelle, ihre Höhe dynamisch anzupassen und eine bestimmte Anzahl von Zellen anzuzeigen, ohne zu scrollen. Das Scrollen wird in dem Moment angezeigt, in dem wir die Grenze für die Höhenbeschränkung erreichen.
Alle drei Funktionen des Interface Builder können miteinander kombiniert werden. Sie bieten mehr Flexibilität für die Optionen der 
UIView ohne dass zusätzliche Einschränkungen oder 
UIView .
2. Die Fähigkeit, das Ergebnis ihrer Aktionen sofort zu sehen
Wenn Sie die Größe des 
UIView , ein paar Punkte zur Seite verschoben oder die Hintergrundfarbe geändert haben, sehen Sie sofort, wie es zur Laufzeit aussieht, ohne die Anwendung starten zu müssen. Sie müssen sich nicht wundern, warum eine Schaltfläche nicht auf dem Bildschirm angezeigt wurde oder warum das Verhalten von 
UIView nicht wie gewünscht ist.
Die Verwendung von 
@IBInspectable zeigt diesen Vorteil noch interessanter. Fügen Sie 
UILabel zwei 
UILabel und zwei Eigenschaften 
RedView :
 final class RedView: XibView { @IBOutlet weak var titleLabel: UILabel! @IBOutlet weak var subtitleLabel: UILabel! @IBInspectable var title: String = "" { didSet { titleLabel.text = title } } @IBInspectable var subtitle: String = "" { didSet { subtitleLabel.text = subtitle } } } 
Im 
Attributinspektor für 
RedView zwei neue Felder 
RedView - 
Title und 
Subtitle , die wir als 
@IBInspectable markiert 
@IBInspectable :

Wenn wir versuchen, Werte in diese Felder einzugeben, sehen wir sofort, wie alles zur Laufzeit aussieht:

Sie können alles steuern: 
cornerRadius , 
borderWidth , 
borderColor . Zum Beispiel erweitern wir die Basisklasse 
UIView :
 extension UIView { @IBInspectable var cornerRadius: CGFloat { set { layer.cornerRadius = newValue } get { return layer.cornerRadius } } @IBInspectable var borderWidth: CGFloat { set { layer.borderWidth = newValue } get { return layer.borderWidth } } @IBInspectable var borderColor: UIColor? { set { layer.borderColor = newValue?.cgColor } get { return layer.borderColor != nil ? UIColor(cgColor: layer.borderColor!) : nil } } @IBInspectable var rotate: CGFloat { set { transform = CGAffineTransform(rotationAngle: newValue * .pi/180) } get { return 0 } } } 
Wir sehen, dass der Attributes Inspector des 
RedView Objekts 4 weitere neue Felder 
RedView , mit denen Sie jetzt auch spielen können:

3. Zeigen Sie alle Bildschirmgrößen gleichzeitig in der Vorschau an
Also haben wir die erforderlichen Elemente auf den Bildschirm geworfen, ihr Erscheinungsbild angepasst und die erforderlichen Einschränkungen hinzugefügt. Wie können wir herausfinden, ob der Inhalt auf verschiedenen Bildschirmgrößen korrekt angezeigt wird? Natürlich können Sie die Anwendung auf jedem Simulator ausführen, aber es wird viel Zeit in Anspruch nehmen. Es gibt eine bessere Option: Xcode verfügt über einen Vorschaumodus, mit dem Sie mehrere Bildschirmgrößen gleichzeitig anzeigen können, ohne die Anwendung zu starten.
Wir rufen den 
Assistenten-Editor auf , klicken auf das erste Segment der Übergangsleiste und wählen 
Vorschau -> Einstellungen.Storyboard (als Beispiel):

Zuerst sehen wir nur einen Bildschirm, aber wir können so viel hinzufügen, wie wir brauchen, indem wir in der unteren linken Ecke auf „+“ klicken und die erforderlichen Geräte aus der Liste auswählen:

Wenn das Storyboard mehrere Sprachen unterstützt, können Sie außerdem sehen, wie der ausgewählte Bildschirm mit jeder Sprache aussieht:

Die Sprache kann für alle Bildschirme gleichzeitig und für jeden einzeln ausgewählt werden.
4. Entfernen des Vorlagen-UI-Codes
Das Erstellen einer Benutzeroberfläche ohne Interface Builder wird entweder von einer großen Menge an Boilerplate-Code oder von Superklassen und Erweiterungen begleitet, die zusätzliche Wartungsarbeiten erfordern. Dieser Code kann andere Teile der Anwendung infiltrieren und das Lesen und Suchen erschweren. Durch die Verwendung von Storyboards und Xibs kann Code ausgelagert werden, sodass der Schwerpunkt stärker auf der Logik liegt.
5. Größenklassen
Jedes Jahr erscheinen neue Geräte, für die Sie die Benutzeroberfläche anpassen müssen. Das Konzept der 
Merkmalsvariationen und insbesondere der 
Größenklassen , mit denen Sie eine Benutzeroberfläche für jede Größe und Ausrichtung des Bildschirms erstellen können, hilft dabei.
Größenklassen klassifizieren die Höhe (h) und Breite (w) von Gerätebildschirmen in Form von 
kompakt und 
regelmäßig ( 
C und 
R ). Zum Beispiel hat das iPhone 8 eine Größenklasse 
(wC hR) im Hochformat und 
(wC hC) im 
Querformat , und das iPhone 8 Plus hat 
(wC hR) bzw. 
(wR hC) . Die restlichen Geräte finden Sie 
hier .
In einem Storyboard oder Xib für jede der Größenklassen können Sie Ihren eigenen Datensatz speichern. Die Anwendung verwendet je nach Gerät und Bildschirmausrichtung zur Laufzeit den entsprechenden Datensatz, um die aktuelle Größenklasse zu ermitteln.
Wenn einige Layoutparameter für alle Größenklassen gleich sind, können sie in der bereits standardmäßig ausgewählten Kategorie " Beliebig " konfiguriert werden .Konfigurieren Sie beispielsweise die Schriftgröße abhängig von der Größenklasse. Wir wählen das iPhone 8 Plus-Gerät für die Anzeige im Storyboard im Hochformat aus und fügen eine neue Bedingung hinzu für font: Wenn die Breite Normal ist (setzen Sie alles andere auf „Beliebig“), sollte die Schriftgröße 37 sein: Wenn wir nun die Bildschirmausrichtung ändern, die Schriftgröße erhöhen - eine neue Bedingung wird funktionieren, da das iPhone 8 Plus im Querformat eine Größenklasse (wR hC) hat . Im Storyboard können Sie je nach Größenklasse auch Ansichten ausblenden, Einschränkungen aktivieren / deaktivieren und deren Wert ändern
Wenn wir nun die Bildschirmausrichtung ändern, die Schriftgröße erhöhen - eine neue Bedingung wird funktionieren, da das iPhone 8 Plus im Querformat eine Größenklasse (wR hC) hat . Im Storyboard können Sie je nach Größenklasse auch Ansichten ausblenden, Einschränkungen aktivieren / deaktivieren und deren Wert ändernconstantund vieles mehr. Weitere Informationen darüber , wie all dies zu tun, können Sie lesen hier .Im obigen Screenshot ist das untere Feld mit der Auswahl des Geräts zur Anzeige des Layouts zu beachten. Sie können damit schnell die Anpassungsfähigkeit der Benutzeroberfläche auf jedem Gerät und bei jeder Bildschirmausrichtung überprüfen und die Größenklasse der aktuellen Konfiguration (neben dem Gerätenamen) anzeigen. Unter anderem befindet sich rechts eine Schaltfläche " Für Eigenschaften variieren" . Ihr Zweck besteht darin, Merkmalsvariationen nur für eine bestimmte Kategorie von Breite, Höhe oder Breite und Höhe gleichzeitig zu ermöglichen. Wenn Sie beispielsweise ein iPad mit einer Größenklasse (wR hR) auswählen , klicken Sie auf „Für Merkmale variieren “ und aktivieren Sie das Kontrollkästchen neben Breite und Höhe. Jetzt gelten alle nachfolgenden Layoutänderungen nur für Geräte mit (wR hR), bis wir auf Done Varying klicken .Fazit
Wir haben gesehen, dass Storyboards ihre Stärken und Schwächen haben. Meiner Meinung nach sollten Sie die Verwendung nicht vollständig ablehnen. Bei richtiger Anwendung bringen sie große Vorteile und helfen, Aufgaben effektiv zu lösen. Sie müssen nur lernen, wie Sie Argumente wie "Ich mag keine Storyboards" oder "Ich bin es gewohnt, dies zu tun" priorisieren und vergessen.