动画时如何以编程方式禁用约束
How to programmatically disable constraint when animating
我有一个固定宽度固定在左侧的视图。我希望此视图通过将其锚定到右侧(从而删除左锚点)来设置动画(从左向右移动)。我该怎么做呢?
我尝试设置优先级,但我不确定语法。我也试过禁用约束,但没有用。
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()
}
}
目前,宽度限制被打破,因为我们正在分配一个左右锚点。
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x6000020b8eb0 UIView:0x7fc846d551d0.width == 15.35 (active)>
-- 编辑--
我已经尝试创建一个实例变量来保存约束。
let leftCons = sparkleView.leftAnchor.constraint(equalTo: leftAnchor)
leftCons.isActive = true
然后我尝试修改优先级
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.'
相反,我需要将其设置为非活动状态(来自答案)
leftCons.active = false
-- 如果有兴趣,请更正代码.. --
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
let leftCons = sparkleView.leftAnchor.constraint(equalTo: leftAnchor)
leftCons.isActive = true
layoutIfNeeded()
leftCons.isActive = false
sparkleView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
UIView.animate(withDuration: 0.5, animations: {
self.layoutIfNeeded()
}) { (_) in
sparkleView.removeFromSuperview()
}
}
您需要创建一个变量
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
note: above 3 constraints create a conflict as the view can't be pinned to left and right at the same time with a width constraint that why you see the conflict break => NSLayoutConstraint:0x6000020b8eb0 UIView:0x7fc846d551d0.width == 15.35 (active)
不管主动分配所以那些
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
关于这次崩溃
'Mutating a priority from required to not on an installed constraint (or vice-versa) is not supported
激活前需要设置优先级
leftCon.priority = UILayoutPriorityDefaultLow
leftCon.isActive = true
我有一个固定宽度固定在左侧的视图。我希望此视图通过将其锚定到右侧(从而删除左锚点)来设置动画(从左向右移动)。我该怎么做呢?
我尝试设置优先级,但我不确定语法。我也试过禁用约束,但没有用。
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()
}
}
目前,宽度限制被打破,因为我们正在分配一个左右锚点。
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x6000020b8eb0 UIView:0x7fc846d551d0.width == 15.35 (active)>
-- 编辑--
我已经尝试创建一个实例变量来保存约束。
let leftCons = sparkleView.leftAnchor.constraint(equalTo: leftAnchor)
leftCons.isActive = true
然后我尝试修改优先级
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.'
相反,我需要将其设置为非活动状态(来自答案)
leftCons.active = false
-- 如果有兴趣,请更正代码.. --
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
let leftCons = sparkleView.leftAnchor.constraint(equalTo: leftAnchor)
leftCons.isActive = true
layoutIfNeeded()
leftCons.isActive = false
sparkleView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
UIView.animate(withDuration: 0.5, animations: {
self.layoutIfNeeded()
}) { (_) in
sparkleView.removeFromSuperview()
}
}
您需要创建一个变量
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
note: above 3 constraints create a conflict as the view can't be pinned to left and right at the same time with a width constraint that why you see the conflict break => NSLayoutConstraint:0x6000020b8eb0 UIView:0x7fc846d551d0.width == 15.35 (active)
不管主动分配所以那些
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
关于这次崩溃
'Mutating a priority from required to not on an installed constraint (or vice-versa) is not supported
激活前需要设置优先级
leftCon.priority = UILayoutPriorityDefaultLow
leftCon.isActive = true