Ios 使用嵌套的UIStackView隐藏UIStackView

Ios 使用嵌套的UIStackView隐藏UIStackView,ios,swift,uiview,uistackview,Ios,Swift,Uiview,Uistackview,前言:我瞥了一眼,它并没有解决我的问题。下面是一个例子,显示了我遇到的错误 我有一个带有垂直UIStackView的UIStackView控制器,其中包含嵌套的水平UIStackView 有两个可切换的uistackview。如果显示UIStackViewNumber1,则将隐藏UIStackViewNumber2,反之亦然。我最初将视图设置为同时显示这两个视图,但它太拥挤了 UIStackView stackViewThatDoesntMove stackViewNumber1

前言:我瞥了一眼,它并没有解决我的问题。下面是一个例子,显示了我遇到的错误

我有一个带有垂直
UIStackView
UIStackView控制器,其中包含嵌套的水平
UIStackView

有两个可切换的
uistackview
。如果显示
UIStackViewNumber1
,则将隐藏
UIStackViewNumber2
,反之亦然。我最初将视图设置为同时显示这两个视图,但它太拥挤了

UIStackView
    stackViewThatDoesntMove
    stackViewNumber1
    stackViewNumber2
    stackViewThatDoesntMove
如果我不隐藏任何内容,一切都正常,没有自动布局错误。每个
UIStackView
都有嵌套的堆栈视图,其中包含按钮、标签、滑块等。我发现视图太拥挤,所以我想我应该设置隐藏其中一个堆栈视图并设置更改动画,如下所示:

stackViewNumber2.isHidden = true

UIView.animate(withDuration: 0.33,
               options: [.curveEaseOut],
               animations: {
                self.stackViewNumber1.layoutIfNeeded()
                self.stackViewNumber2.layoutIfNeeded()
                self.view.layoutIfNeeded()
                    },
               completion: nil)
}
虽然我在模拟器和物理设备上得到了预期的结果,但当我隐藏其中一个UIStackView时,我的控制台就充满了自动布局错误

我看了一眼,我的问题似乎很简单。我用最少的“簿记”方法,将
stackViewNumber2
包装在
UIView
中。我最终得到了与我最初没有在
UIView
中包装
stackViewNumber1
时相同的一组错误

我还阅读并尝试使用arrangedSubviews()设置约束
isActive=false
,如下所示:

for subview in stackViewNumber2.arrangedSubviews {
    for constraint in subview.constraints {
        constraint.isActive = false
    }
}

stackViewNumber2.updateConstraints()
// then run animation block to update view
// 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!
有没有更有效的方法隐藏嵌套的
UIStackViews
而不添加约束的
IBOutlet
,确保它不是弱的,并且对
isActive
是否为
true
/
false
进行簿记


我认为我的问题与嵌套的StackView有关,但我不知道如何解决它。感谢您的阅读,我欢迎您就如何隐藏包含嵌套
UIStackView的
UIStackView
而不是隐藏的
UIStackView提出建议。我认为最好删除stackView本身

myStackView.removeArrangedSubview(playButton)
playButton.removeFromSuperview()

希望能有所帮助。

我一开始想设置隐藏一个视图和取消隐藏另一个视图的动画,但在开始时,我尝试从superview中删除
stackViewNumber1
,并将其替换为
stackViewNumber2
。最终的结果是非常干净,只需最少的簿记,无需将大量的
@IBOutlets
拖到viewController上更新约束等

parentStackView
的视图按照它们在
Main.storyboard
中的显示顺序存储在堆栈的
arrangedSubviews()
数组中

在本例中,
arrangedSubview
数组如下所示:

[topStackView,stackViewNumber1,stackViewNumber2,停止按钮]

我只需要知道
parentStackView
stackViewNumber1
stackViewNumber2
,所以我将3个插座拖到了故事板上,如下所示:

for subview in stackViewNumber2.arrangedSubviews {
    for constraint in subview.constraints {
        constraint.isActive = false
    }
}

stackViewNumber2.updateConstraints()
// then run animation block to update view
// 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
不是
。原因是我想把它们留在身边,这样我就可以把它们换进换出。将2个
UIStackView
出口更改为
weak
后,我没有发现对内存使用有任何不利影响

最终结果:我在初始方法中遇到的大量自动布局错误在没有大量簿记的情况下消失了

更新:

再加上一点修补,我的动画也开始工作了。代码如下:

    UIView.animate(withDuration: 0.25,
                   delay: 0,
                   usingSpringWithDamping: 2.0,
                   initialSpringVelocity: 10.0,
                   options: [.curveEaseOut],
                   animations: {
                    self.view.layoutIfNeeded()
    },
                   completion: nil)

在动画块内更改隐藏属性是否会产生任何不同的效果。如果需要,请停止布局?@agibson007感谢阅读。不,它没有任何不同的效果。嵌套的StackView包含什么?他们是在用内容来衡量自己,还是你在设置内容。还有什么设置垂直保持水平。只是想想象一下,可能是什么阻碍。另外,如果在动画块中隐藏这些stackview的子视图,则会发生什么,而不是禁用约束和隐藏内部stackview。一个是三个UIButton的水平堆栈。其他的是UISlider,旁边有一个UITextField(也是水平的)。外部的stackview呢?我将运行一个更干净的测试,没有错误,没有簿记!我将在下面发布我的最终解决方案,它主要基于您的解决方案。非常感谢。