AutoLayout常量更改不动画

时间:2017-09-29 23:09:01

标签: ios autolayout

我想通过修改contentView的顶级约束常量来从底部向contentView设置动画。它目前设置为screenBounds.height contentView在超级视图的底部也有一个底部约束。

以下代码可以正常使用:

func transition() {
    // animate content view up
    contentViewTopConstraint.constant = contentViewDestinationY // CGFloat value: 50

    UIView.animate(withDuration: 0.6, animations: {
        // apply changes
        self.view.layoutIfNeeded()
    })
}

现在,下面的代码片段动画(但视图消失):

@objc func dismissTransition() {
    // animate content view down
    contentViewYConstraint.constant = screenBounds.height // ~ 834 on regular iPads

    UIView.animate(withDuration: 0.6, animations: {
        // apply changes
        self.view.layoutIfNeeded()
    })
}

由于函数代码实际上没有区别,我认为@objc可能会干扰动画。由于我从dismissTransition()拨打UITapGestureRecognizer,我需要标记 我创建了一个包装器:

let tap = UITapGestureRecognizer(target: self, action: #selector(_ dismissTransition))

@objc func dismissTransition() {
    dismissTransition()
}

......但这并没有改变任何事情。

如果我选择的值低于screenBounds.height,我注意到它 动画:即使用200个动画就好了。
这导致我怀疑底部约束干扰动画:

  • 我将其优先级设置为750,而最高约束的优先级为1000. - 没有变化。

  • 我在layoutIfNeeded中调用dismissTransition()之前尝试停用动画块外的底部约束。 - 没有变化。

说实话,我在这里已经没有想法,所以如果有人知道为什么会这样,我会很感激任何指导。
谢谢!

PS:Xcode 9,iOS 11

更新

我找到了原因:我使用UIView的扩展名来轻松设置如下所示的转角半径:

func set(corners: UIRectCorner, radius: CGFloat) {
    let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
    let mask = CAShapeLayer()
    mask.path = path.cgPath
    self.layer.mask = mask
}

评论view.set(corners:radius:)时(我在viewDidLayoutSubviews内部调用,在其他地方执行时无法正常工作),它会正常动画。
如何更改代码以防止动画?

1 个答案:

答案 0 :(得分:0)

终于找到了解决方案 正如我最近对我的帖子所做的更新中所述,我认为这种奇怪行为的原因是一个应该围绕我视角的延伸。
通过使用@belous in this thread提供的以下代码,我能够完成所有工作,是的!

let view = UIView()
view.clipsToBounds = true
view.layer.cornerRadius = 10
view.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner]