layoutSubviews的调用机制

layoutSubviews什么时候被调用?

为了方便描述,假设视图结构如下:

父视图包含子视图1子视图2

  1. init不会调用layoutSubviews,即使使用了init(frame: CGRect)进行初始化。
  2. 当调用addSubview(:)将子视图2加入父视图的时候,子视图2和父视图的layoutSubviews会被调用,但是子视图1的layoutSubviews方法不会被调用。
  3. 当我们设置子视图2的frame的时候,如果framesize有变化,同结论2addSubview;如果framesize没有变化,则不会有layoutSubviews被调用。
  4. 当调用removeFromSuperview将视图2从父视图中删除的时候,只有父视图的layoutSubviews会被调用。
  5. 当旋转设备的时候,只有根视图的layoutSubviews会被调用。
  6. 当滑动UIScrollView的时候,UIScrollViewlayoutSubviews会被调用。

auto layout和autoSizing

以上结论有个前提:视图通过设置frame或者autoSizing机制确定位置和大小,不使用auto layout。

auto layout和autoSizing的区别:autoSizing确定的是子视图和父视图之间的位置大小关系,auto layout确定的是子视图、父视图以及兄弟视图之间的位置大小关系。

在使用auto layout的时候,当调用addSubview(:)将子视图2加入父视图的时候,子视图2和父视图的layoutSubviews会被调用,同时子视图1的layoutSubviews方法也会被调用。设置frameremoveFromSuperview有类似的结论。

setNeedsLayoutlayoutIfNeeded

  • setNeedsLayout:如果一个视图调用了setNeedsLayout,那么在下一个更新周期该视图的layoutSubviews会被调用。
  • layoutIfNeeded:如果一个视图调用了layoutIfNeeded,那么该视图的layoutSubviews会被立刻调用。