内容概览:
• AutoLayout在iOS 12的性能提升
• AutoLayout内部原理和直觉
• 构建高效的布局
AutoLayout在iOS 12的性能提升
灰色为iOS 11上的表现,蓝色为iOS 12上的表现。
AutoLayout内部原理与我们的直觉
假如你需要构建如下布局:
这样创建约束是不可取的,因为updateConstraints方法可能会在一秒内执行120次!
updateConstraints方法在做什么?
首先,需要介绍渲染循环(Render Loop)。也就是界面控件绘制的流程。
可以看到,渲染循环主要分为更新约束、布局、展示这三个子过程。
首先更新约束,顺序是从子视图到父视图,一直到 UIWindow,依次执行 updateConstraints() 方法。
然后是布局,顺序是从 UIWindow 开始,从父视图到子视图,依次执行 layoutSubviews() 方法。
最后是展示,顺序与布局流程相同,依次执行 draw(_ rect: CGRect) 方法。
相关的方法如下所示:
以set
开头的方法可以设置标记,在下一次渲染循环(Render Loop)时就会执行相应的流程。
以IfNeeded
结尾的方法,可以让相应的流程在当前渲染循环(Render Loop)就执行。
所以,同样地,也不要这样做!
添加 静态约束(不需要做后续的更改) 的正确方式,应该是这样:
或者,通过Xib来添加静态约束。
启用一个约束
AutoLayout内部实现原理
- 首先,将View放到Window上,并添加相应的约束;
- 布局引擎会在updateConstraints()过程中生成与约束相关的方程式;
- 在layoutSubviews()过程中,View会从布局引擎中取出方程式计算的结果并用于View的布局。
计算的结果,实际上就是这四个参数:minX, minY, width, height。
当约束发生变化时,布局引擎又会根据新的方程式计算新的结果,并通知View去调用父视图的setNeedsLayout()方法。
本地布局和全局布局
不相关的视图之间不要建立约束关系。
比如,上图中的text1和text3不要创建对齐的约束,这会导致AutoLayout性能下降!
添加不交互的布局时,布局的数量对布局性能的影响呈线性增长。
如果可以和直接的父视图(self.superview)或者直接父视图中的兄弟视图建立约束,就不要和其他视图建立约束,因为这样的约束性能最好。
实际上,布局引擎就是一个布局缓存和依赖记录器。
最后,后续的Instruments会增加Layout调试组件,敬请期待。
使用工具调试布局的性能问题可以让我们免于直觉的误导。
构建高效的布局
假设你需要构建如下布局:
实际的效果图:
可以使用Instruments中的Layout诊断工具进行诊断:
不过,遗憾的是Xcode 10.2中并未发现此工具😂。可能还需要等到后续的Xcode版本才能用上。
仔细观察布局,对于控件1的布局,我们可以通过修改控件隐藏/显示属性来进行控制,所以只有控件2真正需要改变布局的约束。而控件2涉及到的约束其实并不多,通过两组约束就可以进行调控。
约束波动:
- 避免移除所有约束;
- 对于静态约束,只添加一次;
- 只改变需要改变的约束;
- 隐藏View,而不是removeFromSuperview();
intrinsicContentSize属性:
- 不是所有的View都需要它;
- 不以View作为内容的View:
- UIImageView 返回image的size;
- UILabel 返回text的size,所以长文本可能会造成性能问题;
- UIView使用它来创建约束;
- 选择性地重写来提高文本控件布局性能;
- 直接返回文本的size,而不是让系统去计算文本的size;
- 使用UIView.noIntrinsicMetric和约束;
override var intrinsicContentSize: CGSize {
// 避免文本size的计算,让约束决定文本的size
return CGSize(width: UIView.noIntrinsicMetric, height: UIView.noIntrinsicMetric)
}
systemLayoutSizeFitting(_ targetSize:)方法
- 从布局引擎取出计算结果;
- 在结合frame使用的时候,需要用到它。
在调用systemLayoutSizeFitting(_ targetSize:)方法时,具体执行流程如下:
- 创建布局引擎;
- 添加约束;
- 计算布局;
- 顶部View的Size被返回;
- 布局引擎被废弃;
所以,使用这个方法前需要考虑性能问题,毕竟每次调用都会创建一个新的布局引擎。
参考文章:
High Performance Auto Layout
转载请注明出处,谢谢~