Obwohl mit dem Aufkommen von SwiftUI die Relevanz des automatischen Layouts rapide abnimmt, während dieser Mechanismus immer noch aktiv genutzt wird, kann die Bibliothek für diejenigen nützlich sein, die die Benutzeroberfläche direkt im Code erstellen (oder ändern).
Diese Art der Erstellung einer Schnittstelle weist eine Reihe von Nachteilen auf, die ihre Verwendung einschränken:
- Sehr unpraktisch organisiert die Erstellung von NSLayoutConstraint-Elementen.
- Schlechte Sichtbarkeit - Wenn Sie sich den Code ansehen, ist es schwierig zu verstehen, wie die Benutzeroberfläche aussehen wird.
- Viel Routinecode. Um jede Ansicht zu platzieren, sind durchschnittlich etwa 3 Einschränkungen erforderlich, d.h. drei Zeilen des gleichen Codetyps.
- Die mühsame Erstellung dynamisch wechselnder Schnittstellen: Es ist erforderlich, Einschränkungen in separaten Variablen zu speichern, damit Sie sie später ändern können. Außerdem werden häufig redundante Einschränkungen erstellt und unnötige "deaktiviert".
Das erste Problem kann leicht gelöst werden, indem die Standardmethoden zum Erstellen von Einschränkungen in etwas Menschlicheres eingeschlossen werden. Und dies ist beispielsweise in SnapKit , TinyConstraints und anderen ähnlichen Bibliotheken bereits gut implementiert .
Sie müssen jedoch immer noch viel von der gleichen Art von Code schreiben, und es bleiben Probleme mit der Sichtbarkeit und dynamischen Änderungen am Layout. UIStackView löst diese Probleme auf elegante Weise, aber leider ist in UIStackView das Layout einzelner Elemente sehr begrenzt. Daher entstand die Idee eines Container-UIView, das das Layout des Stapels seiner Unteransichten verwaltet, jedoch die Position jeder Unteransicht individuell konfigurieren kann.
Dieser Ansatz liegt BoxView zugrunde und hat sich als sehr effektiv erwiesen. Mit BoxView können Sie die manuelle Erstellung von Einschränkungen fast vollständig eliminieren. Fast die gesamte Benutzeroberfläche ist als System verschachtelter BoxViews aufgebaut. Infolgedessen wurde der Code viel kürzer und klarer, die Vorteile machen sich insbesondere bei dynamischen Benutzeroberflächen bemerkbar.
BoxView ähnelt in vielerlei Hinsicht dem Standard-UIStackView, verwendet jedoch unterschiedliche Regeln für die Platzierung von Unteransichten: Darin können Sie Einrückungen und Größen für jede Unteransicht einzeln festlegen. Zum Erstellen eines Layouts verwendet BoxView ein Array von Elementen vom Typ BoxItem, das alle Ansichten enthält, die angezeigt werden müssen, sowie Informationen zum Anordnen dieser Elemente. Und dies erfordert überhaupt nicht viel Code - die meisten Layoutparameter werden standardmäßig verwendet und nur die erforderlichen Werte werden explizit angegeben.
Die wesentliche Eigenschaft von BoxView besteht darin, dass nur die angegebenen Einschränkungen für die hinzugefügten Unteransichten erstellt werden und sonst nichts. Daher kann es ohne Einschränkungen in Verbindung mit anderen Bibliotheken und Layoutmethoden verwendet werden.
Als Beispiel sollten Sie ein einfaches Anmeldeformular mit BoxView erstellen (Der vollständige Beispielcode mit einer schrittweisen Beschreibung ist im BoxViewExample- Projekt auf github verfügbar ).
Um ein solches Layout in BoxView zu erstellen, reichen einige Codezeilen aus:
nameBoxView.items = [nameImageView.boxed.centerY(), nameField.boxed]
passwordBoxView.items = [passwordImageView.boxed.centerY(), passwordField.boxed]
boxView.insets = .all(16.0)
boxView.spacing = 20.0
boxView.items = [
titleLabel.boxed.centerX(padding: 30.0).bottom(20.0),
nameBoxView.boxed,
passwordBoxView.boxed,
forgotButton.boxed.left(>=0.0),
loginButton.boxed.top(30.0).left(50.0).right(50.0),
]
Ein BoxItem wird aus jedem UIView mithilfe der Box-Variablen erstellt. Danach kann es auf Auffüllen auf 4 Seiten, Ausrichtung und absolute oder relative Größe eingestellt werden.
Beliebige Layoutelemente können frei hinzugefügt und entfernt werden (auch mit Animation), ohne die Platzierung des Restes zu beeinträchtigen. Fügen wir als Beispiel eine Prüfung auf leere Eingabefelder hinzu, und im Fehlerfall wird eine Meldung direkt unter dem leeren Feld angezeigt:
Und obwohl die Nachricht in das vorhandene Layout "eingebettet" werden sollte, muss nicht einmal der vorhandene Code geändert werden!
func showErrorForField(_ field: UITextField) {
errorLabel.frame = field.convert(field.bounds, to: boxView)
let item = errorLabel.boxed.top(-boxView.spacing).left(errorLabel.frame.minX - boxView.insets.left)
boxView.insertItem(item, after: field.superview, z: .back)
boxView.animateChangesWithDurations(0.3)
}
@objc func onClickButton(sender: UIButton) {
for field in [nameField, passwordField] {
if field.text?.isEmpty ?? true {
showErrorForField(field)
return
}
}
// ok, can proceed with login
}
@objc func onChangeTextField(sender: UITextField) {
errorLabel.removeFromSuperview()
boxView.animateChangesWithDurations(0.3)
}
BoxView unterstützt alle Autolayout-Toolkits: Abstände zwischen Elementen, absolute und relative Größen, Prioritäten, RTL-Sprachunterstützung. Neben UIView können auch unsichtbare Objekte - UILayoutGuides - als Layoutelemente verwendet werden. Das Flex-Layout kann ebenfalls verwendet werden. Natürlich deckt das Layoutschema selbst in Form eines Systems verschachtelter Stapel von UIView nicht zu 100% alle denkbaren Optionen für die relative Anordnung von Elementen ab, dies ist jedoch nicht erforderlich. Für die überwiegende Mehrheit der typischen Benutzeroberflächen ist dies in Ordnung, und für exotischere Fälle können Sie jederzeit auf andere Weise geeignete zusätzliche Einschränkungen hinzufügen. Die Bibliothek enthält auch verschiedene Dienstprogrammmethoden, beispielsweise zum Erstellen von Seitenverhältnisbeschränkungen.
Ein weiteres kleines BeispielAuf Github verfügbar (~ 100 Codezeilen!) veranschaulicht die Verwendung des verschachtelten BoxView-Systems in Verbindung mit anderen Methoden zum Festlegen von Einschränkungen sowie animierte Änderungen der BoxView-Parameter.
BoxView-Projekt auf Github