UIView布局重绘总结
1.setNeedsLayout, layoutIfNeeded
-
setNeedsLayout
:当需要调整UIView
子视图布局时,需要在主线程调用该方法。该方法记录请求并立即返回(即异步执行),等待下一个更新周期更新视图。因此,可以将多个视图布局更新合并到一个update cycle,这样有助于提高性能。需要注意的是,我们无法知道下个update cycle在何时发生。 -
layoutIfNeeded
:强制视图立即更新其布局,即同步执行。当使用Auto Layout时,布局引擎根据约束的变化更新视图的位置。该方法的接收者将作为根视图,布局时也将从视图树的根视图开始。如果没有待处理的布局更新,则此方法将直接退出,而不会修改布局,或调用任何与布局有关的方法。
链接:https://www.jianshu.com/p/58f53e600a94
2.drawRect, layoutSubviews
-
drawRect
1、如果在UIView初始化时没有设置rect大小,将直接导致drawRect不被自动调用。drawRect调用是在Controller->loadView,Controller->viewDidLoad,两方法之后掉的(所以不用担心在Controller中,View的drawRect就开始画了),这样可以在控制器中设置一些值给View(如果这些View draw的时候需要用到某些变量值).这样可以在控制器中设置一些值给View(如果这些View draw的时候需要用到某些变量值).
2、该方法在调用sizeToFit后被调用,所以可以先调用sizeToFit计算出size。然后系统自动调用drawRect:方法。
3、通过设置contentMode属性值为UIViewContentModeRedraw。那么将在每次设置或更改frame的时候自动调用drawRect:。
4、直接调用setNeedsDisplay,或者setNeedsDisplayInRect:触发drawRect:,但是有个前提条件是rect不能为0。 -
layoutSubviews
init初始化不会触发layoutSubviews。
1、addSubview会触发layoutSubviews。
2、改变view的Frame(width, height)会触发layoutSubviews,当然前提是frame的值设置前后发生了变化。
3、直接调用setLayoutSubviews。
4、滚动一个UIScrollView会触发layoutSubviews。
5、旋转Screen会触发父UIView上的layoutSubviews事件。
改变一个UIView大小的时候也会触发父UIView上的layoutSubviews事件
PS: 触发父视图 的 layoutSubviews 方法,则所有子视图的 layoutSubviews 方法都会被触发,同时父视图的父视图 layoutSubviews 也会调用(只会调用一层父视图)