
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
DetailViewController
im obigen Beispiel konfiguriert DetailViewController
? 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
DetailViewController
Eigenschaften DetailViewController
nach der Initialisierung festgelegt. DetailViewController
bedeutet, dass sie optional sein müssen. Es ist erforderlich, Fälle zu behandeln, in denen eine Eigenschaft gleich nil
, 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
var
markiert sein, nicht let
. Eine Situation ist also möglich, wenn jemand von außerhalb sie ändern möchte. DetailViewController
sollte 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
UITableViewCell
und UICollectionViewCell
.
- Fehler in den Segmentkennungen.
- Verwenden einer Unterklasse von
UIView
, die nicht mehr vorhanden ist.
- Synchronisation von
IBActions
und IBOutlets
mit 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
UIViewControllers
die 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 ändernconstant
und 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.