Questions:

In one of the WWDC videos, Apple said that the layout is done from top down, ie from superview to subview , after constraints are calculated from bottom up . Display is also done from top down.

layout布局 和 display显示 是自上而下的,而constraint约束的计算是自下而上的。

My questions are: 

  1. At what point in the viewcontroller is a view's frame (origin and size) determined? I tried to log the size of a view (defined using auto layout), but it was always 0 0 0 0, which is odd, because the view is already generated in the simulator;

何时能够确定view controller的view.frame?

For an autoresized view, when is view.frame available?

自动重新布局的视图,其frame属性什么时候开始有效?

  2.  Same question, except this time it is UIImageView.frame. I tried to log to console, even though the size is fit into the constraints, the logged UIImageView frame is 0 0 width_of_original_p_w_picpath height_of_original_p_w_picpath. But for other views like labels, the frame is printed correctly on the console.

It seems like that there is a mysterious auto layout engine that performs transform, and nobody knows what is going on inside the engine, but to check what is thrown onto the simulator display to figure out how the view was rendered by this engine???


 


Answer:

up vote4down voteaccepted

It's not mysterious. It's quite simple! Think of constraints as instructions written down on pieces of paper - the views. Every once in a while, it's layout time! The runtime collects the pieces of paper from the views in order and obeys them - and so you end up with laid out frames.

苹果的运行时在视图需要重新布局时,将这些约束规则按照层次顺序收集起来,并按照这些规则对视图进行布局,设置frame属性。

So if you check sizes of things before layout time, you get the wrong answer because it hasn't happened yet.

And when is layout time? It's whenever the runtime sends views layoutSubviews - in fact, the runtime obeys constraints and performs layout during layoutSubviews. And your view controller can hear about this before or after, with viewWillLayoutSubviews and viewDidLayoutSubviews.

视图什么时候开始布局呢?-> 答:运行时给视图发layoutSubviews消息的时候。事实上,运行时需要按照这个方法中定义的约束来进行视图的布局。而视图控制器可同时知道什么时候要开始布局了viewWillLayoutSubviews,什么时候布局结束了viewDidLayoutSubviews。

I think the part that confuses beginners the most is what happens when a view controller comes into existence. viewDidLoad means it has a view, but that is all; neither the view nor its subviews are in the interface yet, so obviously there can be no layout. Considerably later, we get viewWillAppear:, the view goes into the interface, and now we get layout. So if you check sizes in, say, viewDidAppear:, they will be right.

viewDidLoad:       视图已经加载完成,但尚未开始布局;

viewWillAppear:  视图布局完成,但还未开始显示;

viewDidAppear:   视图完成显示