以编程方式更改自动布局约束后,视图未更新

时间:2014-10-22 16:40:34

标签: ios swift autolayout constraints

事先我必须说我实际上已经获得了我想要的可见效果但却没有令人满意的方式,因为现在,约束需要“破坏”而不是正确更新。

我有一个ViewController,它包含一个UITableView。 tableView的高度可以从0(不可见)到它所拥有的行数不等。通过将当前行数乘以行的高度,在ViewController的viewDidLoad()中计算高度。

我尝试过的第一件事是创建一个@IBOutlet weak var tableHeightConstraint: NSLayoutConstraint!连接到故事板中设置的高度约束。它只有一些随机的初始高度,但它在ViewController的viewDidLoad()中更新为正确的值,后跟在需要时更新视图的方法:

tableHeightConstraint = NSLayoutConstraint(item: tableView, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 0, constant: calculatedTableViewHeight)

// At this point I've tried a variety of methods like the following two but actually none has worked for me
view.layoutIfNeeded()

// or
view.updateConstraints()

// or
view.layoutSubviews()

...甚至在tableView上使用相同的方法,以确保将所有这些放在viewDidLayoutSubviews()中。

所以我接下来尝试的是创建与上面相同的约束,但不是更新我只是将它添加到视图中:view.addConstraint(tableHeightConstraint)。这实际上具有所需的视觉效果,但在日志中我遇到了这两个高度限制的冲突,导致最初的一个突破。我的目标是获得正确而干净的代码,我一直在努力。所以这次我首先从视图中删除了约束,然后再次添加调整后的约束。从视觉上看,一切都很完美,但我仍然没有摆脱相互冲突的限制。

所以我的实际问题是(除了我到目前为止做错了)我怎么能 - 最好 - 只需更新一个现有的约束,然后在任何时候对视图及其子视图进行适当的更新/重新布局,无论是什么时候我首先加载一个视图,或者我是否只想在用户交互时更改一些约束。非常感谢您的帮助!

1 个答案:

答案 0 :(得分:30)

目前,您正在分配新约束,而不是更新当前约束。新约束也未添加到视图层次结构中。

使用IBOutlet引用您在IB中设置的约束的方法是一种很好的方法,但是不需要为该var赋予新的约束,您只需要修改约束的常量:

tableHeightConstraint.constant = calculatedTableHeight

您不需要在这里调用layoutIfNeeded(),因为约束会在您更改常量时自动调用布局传递。 updateConstraints()layoutSubviews()绝对不是您想要的。