在我的Swift应用程序中,我需要多次更新AutoLayout约束,所以我有一个执行此操作的函数。我有一个问题,这个约束有时没有被更新,我已经把问题缩小到它第一次调用函数时更新,但是如果再次调用该函数则没有。
该函数的代码如下所示:
let verticalSpace = NSLayoutConstraint(item: self.prompt, attribute: .top, relatedBy: .equal, toItem: self.view, attribute: .top, multiplier: 1, constant: 10)
NSLayoutConstraint.activate([verticalSpace])
有谁知道造成这种情况的原因是什么?有多少东西需要做才能多次更新一个函数吗?
答案 0 :(得分:1)
您不能拥有“竞争”限制。如果将verticalSpace设置为10,那么将另一个 verticalSpace设置为20,应该使用哪个约束?
您需要做的是删除现有约束(或停用它),然后添加/激活新约束。
或者...
创建您的verticalConstraint并保存对它的引用...然后当您想要更改它时,您可以根据需要更改.constant
。
答案 1 :(得分:0)
试试这个:
let verticalSpace = NSLayoutConstraint(item: self.prompt, attribute: .top, relatedBy: .equal, toItem: self.view, attribute: .top, multiplier: 1, constant: 10)
NSLayoutConstraint.activate([verticalSpace])
view.layoutIfNeeded()
答案 2 :(得分:0)
修改强> 我刚刚通过以下规则实现了这个目标。
要么
第1步:
删除您要更新的约束。
第2步:
再次添加约束。
或
更新约束值。
在这两种情况下,您都应该引用要更新的约束。
如何强>
我刚刚添加了我的演示代码。我已经以编程方式添加了一个视图,并通过按钮点击更改了它的垂直约束。只需查看代码。
upto viewDidLoad方法:
import UIKit
class ViewController: UIViewController {
let someView = UIView()
var topValue:CGFloat = 10
var verticalConstraint:NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
//This below codes are used to add a red color UIView in center which has width and height both 100
someView.backgroundColor = UIColor.red
someView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(someView)
let horizontalConstraint = NSLayoutConstraint(item: someView, attribute: NSLayoutAttribute.centerX, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.centerX, multiplier: 1, constant: 0) //Center horizontally
verticalConstraint = NSLayoutConstraint(item: someView, attribute: NSLayoutAttribute.top, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.top, multiplier: 1, constant: topValue) // center vertically.want to change that constraint later so took a variable.
let widthConstraint = NSLayoutConstraint(item: someView, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 100) //width 100
let heightConstraint = NSLayoutConstraint(item: someView, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 100) //height 100
view.addConstraints([horizontalConstraint, verticalConstraint, widthConstraint, heightConstraint])
}
对于每个按钮,单击topConstant将逐步更新。
这是我提到的要么部分的代码。
self.view.removeConstraint(verticalConstraint)
verticalConstraint = NSLayoutConstraint(item: someView, attribute:
NSLayoutAttribute.top, relatedBy: NSLayoutRelation.equal, toItem:
view, attribute: NSLayoutAttribute.top, multiplier: 1, constant:
topValue)
self.view.addConstraint(verticalConstraint)
这是或部分的代码。
verticalConstraint.constant = topValue
我的buttonClick事件方法基本上就是这样。
@IBAction func updateView(_ sender: Any) {
topValue += 10
//In this case I've removed the previous constraint and add that constraint again with new Value
self.view.removeConstraint(verticalConstraint)
verticalConstraint = NSLayoutConstraint(item: someView, attribute: NSLayoutAttribute.top, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.top, multiplier: 1, constant: topValue)
self.view.addConstraint(verticalConstraint)
//In this case I've just update that constraint value.Commented because we are using first method
//verticalConstraint.constant = topValue
}