前言:我看了this post并没有解决我的问题。这是link to a repo,显示我遇到的错误。
我有一个UIViewController
,其垂直UIStackView
包含嵌套的水平UIStackViews
。
有两个UIStackViews
被切换。如果显示UIStackViewNumber1
,则隐藏UIStackViewNumber2
&反之亦然。我最初将视图设置为显示两者,但它太拥挤了。
UIStackView
stackViewThatDoesntMove
stackViewNumber1
stackViewNumber2
stackViewThatDoesntMove
如果我不隐藏任何内容,一切正常,没有AutoLayout错误。每个UIStackViews
都有嵌套的stackViews,其中包含按钮,标签,滑块等。我发现视图太拥挤了,所以我想我设置了一个stackViews并为变化设置动画,如下所示:
stackViewNumber2.isHidden = true
UIView.animate(withDuration: 0.33,
options: [.curveEaseOut],
animations: {
self.stackViewNumber1.layoutIfNeeded()
self.stackViewNumber2.layoutIfNeeded()
self.view.layoutIfNeeded()
},
completion: nil)
}
虽然我在Simulator和物理设备上获得了所需的结果,但是当我隐藏其中一个UIStackViews时,我的控制台就会出现AutoLayout错误。
我看了this post,我的问题似乎非常简单。我选择了最少的“簿记”方法并将stackViewNumber2
包裹在UIView
中。我最终遇到了一些错误,我没有将stackViewNumber1
包裹在UIView
中。
我还阅读Apple's documentation on UIStackView
并尝试使用arrangeSubviews()来设置约束isActive = false
,如下所示:
for subview in stackViewNumber2.arrangedSubviews {
for constraint in subview.constraints {
constraint.isActive = false
}
}
stackViewNumber2.updateConstraints()
// then run animation block to update view
是否有更有效的方法隐藏嵌套UIStackViews
而不添加IBOutlet
约束,确保它不弱,并记录isActive
是true
是否false
/ UIStackView
?
我认为我的问题与嵌套的stackViews有关,但我无法弄清楚如何解决它。感谢您阅读,我欢迎有关如何隐藏UIStackViews
包含嵌套printf
的建议。
答案 0 :(得分:2)
而不是隐藏我认为删除stackView本身会更好。
myStackView.removeArrangedSubview(playButton)
playButton.removeFromSuperview()
希望它有所帮助。
答案 1 :(得分:1)
我开始希望动画隐藏一个视图并取消隐藏另一个视图,但在Md. Ibrahim Hassan's suggestion,我尝试从超视图中删除stackViewNumber1
并将其替换为stackViewNumber2
。最终的结果是更清晰,只需要最少的簿记,不会将大量@IBOutlets
拖到viewController上以更新约束等。
parentStackView
的视图按照arrangedSubviews()
中显示的顺序存储在堆栈的Main.storyboard
数组中。
在此示例中,arrangedSubviews
数组如下所示:
[topStackView, stackViewNumber1, stackViewNumber2, stopButton]
我只需要了解parentStackView
,stackViewNumber1
和stackViewNumber2
,因此我将3个频道拖到故事板上,如下所示:
// StackViews the viewController needs to know about...
@IBOutlet weak var parentStackView: UIStackView!
// note weak is removed from the following 2 stackViews
@IBOutlet var stackViewNumber1: UIStackView!
@IBOutlet var stackViewNumber2: UIStackView!
从那里,如果我想删除stackViewNumber2
,则以下代码将其删除:
parentStackView.removeArrangedSubview(stackViewNumber2)
// parentStackView.arrangedSubviews() = [topStackView, stackViewNumber1, stopButton]
stackViewNumber2.removeFromSuperview()
parentStackView.insertArrangedSubview(stackViewNumber1, at: 1)
// parentStackView.arrangedSubviews() = [topStackView, stackViewNumber1, stopButton]
现在,假设我要取出stackViewNumber1
并将其替换为stackViewNumber2
:
parentStackView.removeArrangedSubview(stackViewNumber1)
// parentStackView.arrangedSubviews() = [topStackView, stopButton]
stackViewNumber2.removeFromSuperview()
parentStackView.insertArrangedSubview(stackViewNumber2, at: 1)
// parentStackView.arrangedSubviews() = [topStackView, stackViewNumber2, stopButton]
召回stackViewNumber1
和stackViewNumber2
不是weak
。原因是我想保留它们所以我可以交换它们。由于将2 UIStackView
出口更改为weak
,我没有发现对内存使用产生任何负面影响。
最终结果:我的初始方法遇到的大量AutoLayout错误消失了,没有大量的簿记。
更新:
通过更多的修修补补,我也得到了动画效果。这是代码:
UIView.animate(withDuration: 0.25,
delay: 0,
usingSpringWithDamping: 2.0,
initialSpringVelocity: 10.0,
options: [.curveEaseOut],
animations: {
self.view.layoutIfNeeded()
},
completion: nil)