动画化 UIStackView 子视图会导致布局问题

Animating UIStackView subviews causes layout issues

我有一个 UIStackView,里面有几个排列好的视图,可以使用按钮显示和隐藏。 我通过以下方式为更改设置动画: - 最初将某些子视图的 alpha 设置为 0 和 isHidden = true - 在动画块中,切换哪个子视图具有 alpha = 1 和 isHidden = false

我创建了一个 playground 来展示这个问题:https://gist.github.com/krummler/d0e8db8cb037ae7202f7d801d3114111

简而言之,这适用于两个视图:在任何两个子视图之间切换都可以。按第三次时,视图崩溃并拒绝返回。在那之后,显示子视图变得一团糟。有趣的是,当动画被注释掉时,它不会显示此行为。

我的问题: - 我是否遗漏了什么或者我是否遇到了 UIKit 中的错误? - 我该如何解决这个问题,或者是否有更好的方法来实现我想要做的事情?

很难说 UIStackView 是如何实现的,但它可能会在 isHidden 被修改时尝试更新其布局,即使值实际上并没有改变。

也许这是一个 UIKit 错误,但作为解决方法,您可以修改 resetSubviews(to:) 实现,使其仅在状态实际发生变化时设置 isHidden

    private func resetSubviews(to view: UIView) {
        view1.alpha = view == view1 ? 1 : 0
        view2.alpha = view == view2 ? 1 : 0
        view3.alpha = view == view3 ? 1 : 0
        view4.alpha = view == view4 ? 1 : 0

        let updateIsHiddenForView = { (viewToUpdate: UIView) in
            let isHidden = view != viewToUpdate
            if isHidden != viewToUpdate.isHidden {
                viewToUpdate.isHidden = isHidden
            }
        }
        updateIsHiddenForView(view1)
        updateIsHiddenForView(view2)
        updateIsHiddenForView(view3)
        updateIsHiddenForView(view4)
    }