layoutSubviews的调用机制
layoutSubviews什么时候被调用?
为了方便描述,假设视图结构如下:
父视图包含子视图1和子视图2。
init不会调用layoutSubviews,即使使用了init(frame: CGRect)进行初始化。- 当调用
addSubview(:)将子视图2加入父视图的时候,子视图2和父视图的layoutSubviews会被调用,但是子视图1的layoutSubviews方法不会被调用。 - 当我们设置子视图2的
frame的时候,如果frame的size有变化,同结论2addSubview;如果frame的size没有变化,则不会有layoutSubviews被调用。 - 当调用
removeFromSuperview将视图2从父视图中删除的时候,只有父视图的layoutSubviews会被调用。 - 当旋转设备的时候,只有根视图的
layoutSubviews会被调用。 - 当滑动
UIScrollView的时候,UIScrollView的layoutSubviews会被调用。
auto layout和autoSizing
以上结论有个前提:视图通过设置frame或者autoSizing机制确定位置和大小,不使用auto layout。
auto layout和autoSizing的区别:autoSizing确定的是子视图和父视图之间的位置大小关系,auto layout确定的是子视图、父视图以及兄弟视图之间的位置大小关系。
在使用auto layout的时候,当调用addSubview(:)将子视图2加入父视图的时候,子视图2和父视图的layoutSubviews会被调用,同时子视图1的layoutSubviews方法也会被调用。设置frame和removeFromSuperview有类似的结论。
setNeedsLayout和layoutIfNeeded
setNeedsLayout:如果一个视图调用了setNeedsLayout,那么在下一个更新周期该视图的layoutSubviews会被调用。layoutIfNeeded:如果一个视图调用了layoutIfNeeded,那么该视图的layoutSubviews会被立刻调用。