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 parentStackViewe 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, parentStackViewscontiene una matrice dei 4 elementi: Top Stack View, StackViewNumber1, Stack View Number 2 e Stop Button. I loro indici in arrangedSubviewssono rispettivamente 0, 1, 2 e 3. Quando voglio nasconderne uno, lo rimuovo semplicemente parentStackView's arrangedSubviewsdall'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 arrangedSubviewsdall'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 stackViewNumber2secondo, puoi semplicemente inserirlo parentStackView arrangedSubViewsnell'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 viewDidLoade aggiornarlo senza che l'animazione utilizzi view.layoutIfNeeded().