Mousam Mousam - 28 days ago 17
iOS Question

Autolayout: updateConstraints doest not get call on orientation change

I am learning how Auto layout works in iOS. For this I created a sample single view application which has one view controller (which is initial view controller) and one custom View (lets call it a sample view). I added sample view to the view controller in the Main.storyboard with auto-layouting constraints. I added a button and a label to Sample View with auto-layouting constraints. I override layoutSubviews and updateConstraints method in SampleView.m. These overridden methods do nothing but calling their super implementation. I added a break point to both of these methods and start debugging the application. Following are my observation


  1. I found out that updateConstraints is called before the layoutSubviews method in SampleView. However I read few posts/answers where it is mentioned that layoutSubviews is called before updateConstraints. Now I am confused what is the correct mechanism? does updateConstraint called before layoutSubviews or it is vice versa. How auto-layouting system works?

  2. When I rotate the device from portrait to landscape or landscape to portrait, I found out that updateConstraints method of SampleView does not get call automatically (however the layoutSubviews method get called automatically), while I read few posts/answers which says that on rotation, updateConstraints method get call automatically. I am again confused which one is true?

  3. If updateConstrains method does not get call automatically on orientation change then how can we invoke the updateConstraint method on all views in the view hierarchy when the orientation changes? Will calling setNeedsUpdateConstraint on the parent most view, will invoke updateConstraint on all the child views of that view?


Answer

The layout process generally works like this:

First step: updating constraints, happens bottom-up. Triggered by calling [view setNeedsUpdateConstraints], override [view updateConstraints] for custom views. This step solves constraints.

Second step: Layout, happens top-down. Triggered by calling [view setNeedsLayout], [view layoutIfNeeded], override [view layoutSubviews] for custom views. When layoutSubviews get called, we have frames.

Third step: display, happens top-down. Triggered by calling [view setNeedsDisplay], override [view drawRect:] for custom views.

so,

  1. updateConstraints happens before layoutSubviews. Constraints are basically objects added into a view's parent view, describing how to layout the parent view's subviews. So you do need to update constraints before layout happens.

  2. On orientation changes, constraints hasn't changed, therefore I think updateConstraints will not be called.

  3. How can we invoke the updateConstraint method on all views in the view hierarchy when the orientation changes? Constraints don't need to get updated because they are the way about how views should be related to each other. Instead, when orientation changes, the top most view's (UIWindow) frame will be updated, therefore all of its subviews need to update their frame in order to conform to the constraints you has previously set up.

If I am wrong please correct me :)

Comments