Recentemente ho lottato con errori di layout automatico nascondendo un file UIStackView
. Piuttosto che tenere un mucchio di libri e impacchettare pile UIViews
, ho deciso di creare uno sbocco per il mio parentStackView
e punti vendita per i bambini che voglio nascondere / mostrare.
@IBOutlet weak var parentStackView: UIStackView!
@IBOutlet var stackViewNumber1: UIStackView!
@IBOutlet var stackViewNumber2: UIStackView!
Nello storyboard, ecco come appare il mio genitoreStack:
Ha 4 bambini e ciascuno di essi ha una serie di viste in pila al loro interno. Quando nascondi una vista stack, se ha elementi dell'interfaccia utente che sono anche viste stack, vedrai un flusso di errori di layout automatico. Invece di nasconderli, ho deciso di rimuoverli.
Nel mio esempio, parentStackViews
contiene una matrice dei 4 elementi: Top Stack View, StackViewNumber1, Stack View Number 2 e Stop Button. I loro indici in arrangedSubviews
sono rispettivamente 0, 1, 2 e 3. Quando voglio nasconderne uno, lo rimuovo semplicemente parentStackView's
arrangedSubviews
dall'array. Poiché non è debole, rimane nella memoria e puoi semplicemente rimetterlo all'indice desiderato in seguito. Non lo sto reinizializzando, quindi resta in sospeso finché non è necessario, ma non gonfia la memoria.
Quindi, in pratica, puoi ...
1) Trascina nello storyboard IBOutlets per lo stack genitore e per i figli che desideri nascondere / mostrare.
2) Quando vuoi nasconderli, rimuovi lo stack che vuoi nascondere parentStackView's
arrangedSubviews
dall'array.
3) Chiama self.view.layoutIfNeeded()
con UIView.animateWithDuration
.
Nota che gli ultimi due stackView non lo sono weak
. Devi tenerli in giro per quando li riveli.
Diciamo che voglio nascondere stackViewNumber2:
parentStackView.removeArrangedSubview(stackViewNumber2)
stackViewNumber2.removeFromSuperview()
Quindi animalo:
UIView.animate(withDuration: 0.25,
delay: 0,
usingSpringWithDamping: 2.0,
initialSpringVelocity: 10.0,
options: [.curveEaseOut],
animations: {
self.view.layoutIfNeeded()
},
completion: nil)
Se vuoi "scoprire" un stackViewNumber2
secondo, puoi semplicemente inserirlo parentStackView
arrangedSubViews
nell'indice desiderato e animare l'aggiornamento.
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)
Ho scoperto che è molto più facile che fare la contabilità sui vincoli, giocherellare con le priorità, ecc.
Se hai qualcosa che desideri nascondere per impostazione predefinita, puoi semplicemente posizionarlo sullo storyboard e rimuoverlo viewDidLoad
e aggiornarlo senza che l'animazione utilizzi view.layoutIfNeeded()
.