Your conclusions are right. The basic scheme is:
setNeedsUpdateConstraints
makes sure a future call to updateConstraintsIfNeeded
calls updateConstraints
.setNeedsLayout
makes sure a future call to layoutIfNeeded
calls layoutSubviews
.When layoutSubviews
is called, it also calls updateConstraintsIfNeeded
, so calling it manually is rarely needed in my experience. In fact, I have never called it except when debugging layouts.
Updating constraints using setNeedsUpdateConstraints
is pretty rare too, objc.io–a must read about autolayouts–says:
If something changes later on that invalidates one of your constraints, you should remove the constraint immediately and call setNeedsUpdateConstraints. In fact, that’s the only case where you should have to trigger a constraint update pass.
In addition, in my experience, I have never had to invalidate constraints, and not set the setNeedsLayout
in the next line of the code, because new constraints pretty much are asking for a new layout.
The rules of thumb are:
setNeedsLayout
.updateConstraints
method (a recommended way to change constraints, btw), call setNeedsUpdateConstraints
, and most of the time, setNeedsLayout
after that.layoutIfNeeded
.Also, in your animation code, I believe setNeedsUpdateConstraints
is unneeded, since constraints are updated before the animation manually, and the animation only re-lays-out the view based on differences between the old and new ones.
The answer by coverback is pretty correct. However, I would like to add some additional details.
Below is the diagram of a typical UIView cycle which explains other behaviors:
-setNeedsLayout
instead of -setNeedsUpdateConstraints
everything work as expected, but if I change -layoutIfNeeded
with -updateConstraintsIfNeeded
, the animation won't happen.updateConstraints
typically doesn't do anything. It just resolves constraints it doesn't apply them till layoutSubviews
is called. So animation does requires a call to layoutSubviews
.
No this is not necessary. If your constraints haven't been modified UIView will skip call to updateConstraints
. You need to explicitly call setNeedsUpdateConstraint
to modify constraints in the process.
In order to call updateConstraints
you need to do the following:
[view setNeedsUpdateConstraints];
[view setNeedsLayout];
[view layoutIfNeeded];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With