Недавно я боролся с ошибками автоматической компоновки при скрытии UIStackView
. Вместо того, чтобы вести бухгалтерию и упаковывать стопки в UIViews
, я решил создать выход для моего parentStackView
и выходы для детей, которых я хочу скрыть / показать.
@IBOutlet weak var parentStackView: UIStackView!
@IBOutlet var stackViewNumber1: UIStackView!
@IBOutlet var stackViewNumber2: UIStackView!
Вот как выглядит мой parentStack в раскадровке:
![введите здесь описание изображения](https://i.stack.imgur.com/AnBuV.png)
У него 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)
// Then animate it
UIView.animate(withDuration: 0.25,
delay: 0,
usingSpringWithDamping: 2.0,
initialSpringVelocity: 10.0,
options: [.curveEaseOut],
animations: {
self.view.layoutIfNeeded()
},
completion: nil)
Я обнаружил, что это намного проще, чем вести учет ограничений, возиться с приоритетами и т. Д.
Если у вас есть что-то, что вы хотите скрыть по умолчанию, вы можете просто выложить это на раскадровку, удалить в viewDidLoad
и обновить без анимации, используя view.layoutIfNeeded()
.
person
Adrian
schedule
17.03.2017