简体   繁体   English

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

[英]View is not updating after changing auto-layout constraints programmatically

Beforehand I have to say that I actually got the visible effect I've wanted but not in a satisfying way since, right now, constraints need to be "broken" instead of being properly updated. 事先我不得不说我实际上得到了我想要的可见效果,但不是令人满意的方式,因为现在,约束需要被“打破”而不是正确更新。

I got a ViewController which holds a UITableView. 我有一个ViewController,它包含一个UITableView。 The height of that tableView can vary from 0 (not visible) to whatever the number of rows it holds is. tableView的高度可以从0(不可见)到它所拥有的行数不等。 The height is calculated in the ViewController's viewDidLoad() by multiplying the current number of rows by the row's height. 通过将当前行数乘以行的高度,在ViewController的viewDidLoad()中计算高度。

The first thing I've tried was creating an @IBOutlet weak var tableHeightConstraint: NSLayoutConstraint! 我尝试过的第一件事是创建一个@IBOutlet weak var tableHeightConstraint: NSLayoutConstraint! connected to the height constraint set in the storyboard. 连接到故事板中设置的高度约束。 It has just some random initial height but it is updated to the correct value within the ViewController's viewDidLoad() followed by method that updates the view if needed: 它只有一些随机的初始高度,但它在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()

... and even the same methods on tableView just to be sure as well as putting all these in viewDidLayoutSubviews() instead. ...甚至在tableView上使用相同的方法只是为了确保将所有这些放在viewDidLayoutSubviews()

So what I tried next was to create the same constraint as above but instead of updating I just added it to the view: view.addConstraint(tableHeightConstraint) . 所以我接下来尝试创建与上面相同的约束,但不是更新我只是将它添加到视图: view.addConstraint(tableHeightConstraint) This actually had the desired visual effect but in the logs I got a conflict of these two height constraints resulting in a break of the initial one. 这实际上具有所需的视觉效果,但在日志中我遇到了这两个高度限制的冲突,导致最初的一个突破。 As my goal is to get a correct and clean code I've kept trying. 我的目标是获得正确而干净的代码,我一直在努力。 So this time I first removed the constraint from the view before adding the adjusted one again. 所以这次我首先从视图中删除了约束,然后再次添加调整后的约束。 Visually, again, everything was perfect but I still didn't get rid of the conflicting constraints. 从视觉上看,一切都很完美,但我仍然没有摆脱相互冲突的限制。

So my actual question is (besides what I was doing wrong so far) how I can - preferably - just update an existing constraint followed by a proper update/relayout of the view and its subviews at any point, whether it is when I first load a view or whether I just want to change some constraints when the user interacts. 所以我的实际问题是(除了我到目前为止做错了)我怎么能 - 最好 - 只需更新一个现有的约束,然后在任何时候对视图及其子视图进行适当的更新/重新布局,无论是在我第一次加载时一个视图或我是否只想在用户交互时更改一些约束。 Thanks a lot for any help! 非常感谢您的帮助!

Currently, you're assigning a new constraint, instead of updating the current one. 目前,您正在分配新约束,而不是更新当前约束。 The new constraint also hasn't been added to the view hierarchy. 新约束也未添加到视图层次结构中。

Your approach of using an IBOutlet to reference a constraint you set up in IB is a good approach, but instead of assigning a new constraint to that var, you just need to modify the constraint's constant: 您使用IBOutlet引用您在IB中设置的约束的方法是一种很好的方法,但是您只需要修改约束的常量,而不是为该var分配新的约束:

tableHeightConstraint.constant = calculatedTableHeight . tableHeightConstraint.constant = calculatedTableHeight

You shouldn't need to call layoutIfNeeded() here, since constraints handle calling a layout pass automatically when you change their constants. 您不需要在这里调用layoutIfNeeded(),因为约束会在您更改常量时自动调用布局传递。 updateConstraints() and layoutSubviews() are definitely not what you want. updateConstraints()layoutSubviews()绝对不是你想要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM