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
会被立刻调用。