Недавно я столкнулся с ошибками автоматической компоновки при скрытии файла UIStackView
. Вместо того, чтобы вести кучу бухгалтерии и упаковывать стопки UIViews
, я решил создать выход для своих parentStackView
и выходы для детей, которых я хочу скрыть / показать.
@IBOutlet weak var parentStackView: UIStackView!
@IBOutlet var stackViewNumber1: UIStackView!
@IBOutlet var stackViewNumber2: UIStackView!
Вот как выглядит мой parentStack в раскадровке:
У него 4 дочерних элемента, и каждый из них имеет внутри несколько видов стека. Когда вы скрываете представление стека, если у него есть элементы пользовательского интерфейса, которые также являются представлениями стека, вы увидите поток ошибок автоматического макета. Вместо того, чтобы прятаться, я решил удалить их.
В моем примере он parentStackViews
содержит массив из 4 элементов: Top Stack View, StackViewNumber1, Stack View Number 2 и Stop Button. Их индексы в arrangedSubviews
равны 0, 1, 2 и 3 соответственно. Когда я хочу скрыть один, я просто удаляю его из parentStackView's
arrangedSubviews
массива. Поскольку он неслабый, он остается в памяти, и вы можете просто вернуть его в желаемый индекс позже. Я не инициализирую его повторно, поэтому он просто зависает, пока не понадобится, но не раздувает память.
В общем, вы можете ...
1) Перетащите IBOutlets для родительского стека и дочерних элементов, которых вы хотите скрыть / отобразить, на раскадровку.
2) Если вы хотите их скрыть, удалите стек, который вы хотите скрыть из parentStackView's
arrangedSubviews
массива.
3) Звоните self.view.layoutIfNeeded()
с UIView.animateWithDuration
.
Обратите внимание, что последние два stackView - нет weak
. Вам нужно держать их под рукой, пока вы их не покажете.
Скажем, я хочу скрыть stackViewNumber2:
parentStackView.removeArrangedSubview(stackViewNumber2)
stackViewNumber2.removeFromSuperview()
Затем оживите его:
UIView.animate(withDuration: 0.25,
delay: 0,
usingSpringWithDamping: 2.0,
initialSpringVelocity: 10.0,
options: [.curveEaseOut],
animations: {
self.view.layoutIfNeeded()
},
completion: nil)
Если вы хотите «показать» stackViewNumber2
позже, вы можете просто вставить его в нужный parentStackView
arrangedSubViews
индекс и анимировать обновление.
parentStackView.removeArrangedSubview(stackViewNumber1)
stackViewNumber1.removeFromSuperview()
parentStackView.insertArrangedSubview(stackViewNumber2, at: 1)
UIView.animate(withDuration: 0.25,
delay: 0,
usingSpringWithDamping: 2.0,
initialSpringVelocity: 10.0,
options: [.curveEaseOut],
animations: {
self.view.layoutIfNeeded()
},
completion: nil)
Я обнаружил, что это намного проще, чем вести учет ограничений, возиться с приоритетами и т. Д.
Если у вас есть что-то, что вы хотите скрыть по умолчанию, вы можете просто выложить это на раскадровку, удалить viewDidLoad
и обновить без использования анимации view.layoutIfNeeded()
.