Swift 如何在设置动画时以编程方式禁用约束

Swift 如何在设置动画时以编程方式禁用约束,swift,autolayout,nslayoutconstraint,Swift,Autolayout,Nslayoutconstraint,我有一个固定宽度的视图固定在左侧。我希望通过将此视图向右锚定(从而移除左锚定)来设置动画(从左向右移动)。我该怎么做 我尝试设置优先级,但不确定语法。我还尝试禁用约束,但没有成功 fileprivate func sparkle() { let sparkleView = UIView() sparkleView.backgroundColor = UIColor.yellow sparkleView.alpha = 0.5 addSubview(sparkleV

我有一个固定宽度的视图固定在左侧。我希望通过将此视图向右锚定(从而移除左锚定)来设置动画(从左向右移动)。我该怎么做

我尝试设置优先级,但不确定语法。我还尝试禁用约束,但没有成功

fileprivate func sparkle() {
    let sparkleView = UIView()
    sparkleView.backgroundColor = UIColor.yellow
    sparkleView.alpha = 0.5
    addSubview(sparkleView)
    sparkleView.translatesAutoresizingMaskIntoConstraints = false
    sparkleView.topAnchor.constraint(equalTo: topAnchor).isActive = true
    sparkleView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
    sparkleView.widthAnchor.constraint(equalToConstant: frame.width / 5).isActive = true
    sparkleView.leftAnchor.constraint(equalTo: leftAnchor).priority = UILayoutPriorityDefaultLow // Doesn't work
    sparkleView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
    layoutIfNeeded()
    sparkleView.leftAnchor.constraint(equalTo: leftAnchor).isActive = false // Doesn't work
    sparkleView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
    UIView.animate(withDuration: 2, animations: {
        self.layoutIfNeeded()
    }) { (_) in
        sparkleView.removeFromSuperview()
    }
}
目前,宽度约束被打破,因为我们正在分配一个左锚和右锚

然后我尝试修改优先级

leftCons.priority = UILayoutPriorityDefaultLow
但是,这会导致错误

'Mutating a priority from required to not on an installed constraint (or vice-versa) is not supported.  You passed priority 250 and the existing priority was 1000.'
相反,我只需要将其设置为非活动(从答案中)

--如果感兴趣,请更正代码--


您需要创建一个var

var leftCon:NSLayoutConstraint!
然后改变它,你的问题是每一行创建一个新的约束

sparkleView.widthAnchor.constraint(equalToConstant: frame.width / 5).isActive = true
sparkleView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
sparkleView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
注意:以上3个约束会产生冲突,因为视图不能与宽度约束同时固定在左侧和右侧,这就是为什么会看到冲突中断=>NSLayoutConstraint:0x6000020b8eb0 UIView:0x7fc846d551d0.width==15.35(活动)

无论活动分配如何,因此

sparkleView.leftAnchor.constraint(equalTo: leftAnchor).priority = UILayoutPriorityDefaultLow // Doesn't work 
sparkleView.leftAnchor.constraint(equalTo: leftAnchor).isActive = false // Doesn't work
正在运行中,不更改创建的约束,因此

leftCon = sparkleView.leftAnchor.constraint(equalTo: leftAnchor)
leftCon.isActive = true

关于这次事故

'不支持在已安装的约束上将优先级从required变为not(反之亦然)

您需要在激活之前设置优先级

leftCon.priority = UILayoutPriorityDefaultLow
leftCon.isActive = true

是的,这起作用了。旁注——您可以在这里使用let,因为我们从未对它进行过变异。是的,如果您直接在一行中创建它,那么
let
是合适的,上面我的意思是如果它声明为实例varAh,感谢您澄清优先级崩溃!这绝对是有用的信息。
sparkleView.widthAnchor.constraint(equalToConstant: frame.width / 5).isActive = true
sparkleView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
sparkleView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
sparkleView.leftAnchor.constraint(equalTo: leftAnchor).priority = UILayoutPriorityDefaultLow // Doesn't work 
sparkleView.leftAnchor.constraint(equalTo: leftAnchor).isActive = false // Doesn't work
leftCon = sparkleView.leftAnchor.constraint(equalTo: leftAnchor)
leftCon.isActive = true
leftCon.priority = UILayoutPriorityDefaultLow
leftCon.isActive = true