动画子视图AutoLayout约束更改

时间:2018-09-17 13:32:51

标签: ios autolayout nslayoutconstraint uiviewanimation ios-autolayout

许多有关对AutoLayout约束进行动画处理的教程建议更新约束的常量属性,然后在动画块中调用layoutIfNeeded()

我的情况有点棘手。 我有一个包含3个子视图的视图。此超级视图的高度不是固定的-是根据其子视图的高度之和计算得出的。 在某些情况下,我要求这3个子视图之一切换其高度(它在0到30之间变化,即我想平滑地隐藏并显示它)。 代码类似于此:

// In superview
subview1.isVisibleInContext = !subview1.isVisibleInContext

// In subview
class MySubview: UIView {
    @IBOutlet var heightConstraint: NSLayoutConstraint!

    var isVisibleInContext = false {
        didSet {
            updateHeight()
        }
    }

    func toggleHeight() {
        let newHeight = isVisibleInContext ? 30 : 0
        layoutIfNeeded()
        heightConstraint.constant = newHeight
        UIView.animate(withDuration: 0.8) {
            self.layoutIfNeeded()
        }
    }
}

不幸的是,这不符合我的预期。 我可以看到子视图高度的平滑变化,但是在为子视图高度约束设置新值后,将立即重新计算超级视图的高度。

我希望看到子视图的高度随着子视图中的某个子窗口的增大或减小而逐渐增加/减小。

请有人指出我正确的方向。任何帮助表示赞赏。

非常感谢!

2 个答案:

答案 0 :(得分:3)

动画块应位于包含3个UIView的{​​{1}}中。在MySubviews类中,您仅更新高度约束的常量:

在子视图中

MySubview

然后在包含3个func toggleHeight() { let newHeight = isVisibleInContext ? 30 : 0 heightConstraint.constant = newHeight } 的{​​{1}}中为更改设置动画:

处于超级观看状态

UIView

enter image description here

答案 1 :(得分:0)

第一件事,在我的方法中不正确的是执行self.layoutIfNeeded()。研究了这个问题后,我得知我必须在superivew上执行它,如下所示:

self.superview?.layoutIfNeeded()

那也不是有原因的。在这种情况下,主要问题是内部有3个子视图的视图本身就是视图的子视图。因此,要使其正常工作,我必须使用以下代码:

self.superview?.superview?.layoutIfNeeded()

子视图必须知道视图的层次结构绝对不是很好,但是它可以工作。