Auto Layout 的来历
- 在 1997 年,Auto Layout 用到的 Cassowary 算法被发明出来。
Cassowary 能够有效解析线性等式系统和线性不等式系统,用来表示用户界面中那些相等关系和不等关系。基于此 Cassowary 开发了一种规则系统,通过约束来描述视图间的关系。约束就是规则,这个规则能够表示出一个视图相对于另一个视图的位置。
- 在 2011 年, Apple 将 Cassowary 算法运用到来自家的布局引擎 Auto Layout 中。
由于 Cassowary 算法让视图位置可以按照一种简单的布局思路来写,这些简单的相对位置描述可以在运行时动态地计算出视图具体的位置。视图位置的写法简化了,界面相关代码也就更易于维护。
Auto Layout 的生命周期
Auto Layout 不只有布局算法 Cassowary, 还包含了布局在运行时的生命周期等一整套布局引擎系统,用来统一管理布局的创建,更新和销毁。
这一整套布局引擎系统叫做 Layout Engine,是 Auto Layout 的核心,主导着整个界面布局。每个视图在得到自己的布局之前, layout Engine 会将视图,约束,优先级,固定大小通过计算转换成最终的大小和位置。在 Layout Engine 里,每当约束发生变化,就会触发 Deferred Layout Pass,完成后进入监听约束变化的状态。当再次监听到约束变化,即进入下一轮循环中。
Layout Engine 在碰到约束变化后会重新计算布局,获取到布局后调用superview.setNeedLayout()
,然后进入 Deferred Layout Pass。
Deferred Layout Pass 的主要作用是做容错处理,如果这些视图在更新约束时没有确定或缺失布局说明的话,会先在这里做容错处理。
接下来, Layout Engine 会从上到下调用layoutSubviews()
,通过 Cassowary 算法计算各个子视图的位置,算出来后将子视图的 frame 从 Layout Engine 里拷贝出来。
Auto Layout 的性能问题
iOS 12 的 Auto Layout 更多地利用里 Cassowary 算法的界面更新策略,使其真正完成了高效的界面线性策略计算。
iOS 12 之前的性能问题:很多约束变化时都会重新创建一个计算引擎 NSISEnginer 将约束关系重新加进来,然后重新计算,结果就是,涉及到的约束关系多时,新的计算引擎需要重新计算,最终导致计算呈指数级增加。