Ich habe kürzlich mit automatischen Layoutfehlern gerungen, als ich a versteckte UIStackView
. Anstatt ein paar Bücher zu führen und Stapel einzupacken UIViews
, habe ich mich dafür entschieden, eine Steckdose für meine parentStackView
und Steckdosen für die Kinder zu schaffen, die ich verstecken / einblenden möchte.
@IBOutlet weak var parentStackView: UIStackView!
@IBOutlet var stackViewNumber1: UIStackView!
@IBOutlet var stackViewNumber2: UIStackView!
Im Storyboard sieht mein parentStack folgendermaßen aus:
Es hat 4 Kinder und jedes der Kinder hat eine Reihe von Stapelansichten in sich. Wenn Sie eine Stapelansicht ausblenden und UI-Elemente enthalten, die ebenfalls Stapelansichten sind, wird ein Strom von Fehlern beim automatischen Layout angezeigt. Anstatt mich zu verstecken, entschied ich mich, sie zu entfernen.
In meinem Beispiel parentStackViews
enthält es ein Array der 4 Elemente: Top Stack View, StackViewNumber1, Stack View Number 2 und Stop Button. Ihre Indizes in arrangedSubviews
sind 0, 1, 2 bzw. 3. Wenn ich eine ausblenden möchte, entferne ich sie einfach aus dem parentStackView's
arrangedSubviews
Array. Da es nicht schwach ist, bleibt es im Speicher und Sie können es später einfach wieder auf den gewünschten Index setzen. Ich initialisiere es nicht neu, so dass es nur so lange hängt, bis es benötigt wird, aber das Gedächtnis nicht aufbläht.
Im Grunde können Sie ...
1) Ziehen Sie IBOutlets für Ihren übergeordneten Stapel und die untergeordneten Elemente, die Sie ein- oder ausblenden möchten, in das Storyboard.
2) Wenn Sie sie ausblenden möchten, entfernen Sie den Stapel, den Sie aus dem parentStackView's
arrangedSubviews
Array ausblenden möchten .
3) Rufen Sie self.view.layoutIfNeeded()
mit an UIView.animateWithDuration
.
Beachten Sie, dass die letzten beiden StackViews dies nicht sind weak
. Sie müssen sie aufbewahren, wenn Sie sie einblenden.
Angenommen, ich möchte stackViewNumber2 ausblenden:
parentStackView.removeArrangedSubview(stackViewNumber2)
stackViewNumber2.removeFromSuperview()
Dann animiere es:
UIView.animate(withDuration: 0.25,
delay: 0,
usingSpringWithDamping: 2.0,
initialSpringVelocity: 10.0,
options: [.curveEaseOut],
animations: {
self.view.layoutIfNeeded()
},
completion: nil)
Wenn Sie ein stackViewNumber2
späteres "einblenden" möchten , können Sie es einfach in den gewünschten parentStackView
arrangedSubViews
Index einfügen und das Update animieren.
parentStackView.removeArrangedSubview(stackViewNumber1)
stackViewNumber1.removeFromSuperview()
parentStackView.insertArrangedSubview(stackViewNumber2, at: 1)
// Then animate it
UIView.animate(withDuration: 0.25,
delay: 0,
usingSpringWithDamping: 2.0,
initialSpringVelocity: 10.0,
options: [.curveEaseOut],
animations: {
self.view.layoutIfNeeded()
},
completion: nil)
Ich fand das viel einfacher als die Buchhaltung von Einschränkungen, das Herumspielen mit Prioritäten usw.
Wenn Sie etwas haben, das Sie standardmäßig ausblenden möchten, können Sie es einfach im Storyboard auslegen und entfernen viewDidLoad
und aktualisieren, ohne dass die Animation verwendet wird view.layoutIfNeeded()
.