我最近在隐藏UIStackView
. 我没有做一堆簿记和包装堆栈UIViews
,而是选择为我parentStackView
的孩子创建一个出口,为我想要隐藏/取消隐藏的孩子创建一个出口。
@IBOutlet weak var parentStackView: UIStackView!
@IBOutlet var stackViewNumber1: UIStackView!
@IBOutlet var stackViewNumber2: UIStackView!
在情节提要中,这是我的 parentStack 的样子:
它有 4 个孩子,每个孩子里面都有一堆堆栈视图。当您隐藏堆栈视图时,如果它的 UI 元素也是堆栈视图,您将看到一连串自动布局错误。我没有隐藏,而是选择删除它们。
在我的示例中,parentStackViews
包含 4 个元素的数组:顶部堆栈视图、堆栈视图编号 1、堆栈视图编号 2 和停止按钮。它们的索引arrangedSubviews
分别为 0、1、2 和 3。当我想隐藏一个时,我只需将其从parentStackView's
arrangedSubviews
数组中删除。由于它不弱,它会在内存中徘徊,您可以稍后将其放回所需的索引。我没有重新初始化它,所以它只是挂起直到需要它,但不会膨胀内存。
所以基本上,你可以...
1) 将您的父堆栈的 IBOutlets 和您想要隐藏/取消隐藏的子级拖动到情节提要。
2)当你想隐藏它们时,从parentStackView's
arrangedSubviews
数组中删除你想隐藏的堆栈。
self.view.layoutIfNeeded()
3)用调用UIView.animateWithDuration
。
注意最后两个 stackViews 不是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()
。