你尝试过将使用布局锚点创建的相关约束保存到属性中,然后只更改常量吗?例如:
var ticketTop : NSLayoutConstraint?
func setup() {
ticketTop = ticketContainer.topAnchor.constraintEqualToAnchor(self.topAnchor, constant:100)
ticketTop.active = true
}
func update() {
ticketTop?.constant = 25
}
或许更加优雅
根据您对编写扩展的喜好,这里提供一种可能更加优雅的方法,它不使用属性,而是在NSLayoutAnchor
和UIView
上创建扩展方法以帮助更简洁地使用。
首先,您可以编写一个NSLayoutAnchor
的扩展,如下所示:
extension NSLayoutAnchor {
func constraintEqualToAnchor(anchor: NSLayoutAnchor!, constant:CGFloat, identifier:String) -> NSLayoutConstraint! {
let constraint = self.constraintEqualToAnchor(anchor, constant:constant)
constraint.identifier = identifier
return constraint
}
}
这个扩展允许你在创建约束时,通过同一方法调用在锚点上设置标识符。请注意,苹果文档暗示X轴锚点(左、右、前导等)不会让你使用Y轴锚点(顶部、底部等)创建约束,但我并没有观察到这实际上是真的。如果您确实希望进行这种类型的编译器检查,则需要编写单独的扩展来限制NSLayoutXAxisAnchor
、NSLayoutYAxisAnchor
和NSLayoutDimension
(用于宽度和高度约束) 的相同轴锚点类型要求。
接下来,您可以编写一个扩展程序,在UIView
上按标识符获取约束:
extension UIView {
func constraint(withIdentifier:String) -> NSLayoutConstraint? {
return self.constraints.filter{ $0.identifier == withIdentifier }.first
}
}
有了这些扩展,你的代码变为:
func setup() {
ticketContainer.topAnchor.constraintEqualToAnchor(anchor: self.topAnchor, constant:100, identifier:"ticketTop").active = true
}
func update() {
self.constraint(withIdentifier:"ticketTop")?.constant = 25
}
请注意,使用常量或枚举代替魔术字符串名称作为标识符将优于上述方法,但我希望保持回答简短和重点突出。