AutoLayout 自动布局知识总结
约束(constraint)的位置
子视图间的相对约束关系是保存在父视图里面。视图自身的宽高约束是保存在视图本身的约束属性里面。
属性计算公式
1 | item1.attribute1 multiplier ⨉ item2.attribute2 + constant |
常量值(constant)的正负值的含义
一般来说正值表示距离,负值表示重叠。
例如子视图相对于容器视图的边界的约束。正值向内收缩,负值向外扩张。
特别是需要给一个相对父视图边界定位的子视图做滑动动画的时候,理解这一点对正确调整约束的属性值非常重要。
Intrinsic Content Size、Compression Resistance、Content Hugging、Alignment Rect
Alignment Rect : view在自动布局时的边界。自动布局不影响视图的frame值,也不受视图frame的影响。大部分情况下视图的Alignment Rect值和frame的值相同。如果需要视图的触摸或站位尺寸大于内容的显示尺寸时,可以修改Alignment Rect的值来实现。
Intrinsic Content Size : 视图为了展示内容而需要的期望大小。
Compression Resistance : 视图的边界压缩阻力特性。
Content Hugging :视图的边界吸附特性。
Compression Resistance和Content Hugging只有在设置了 Intrinsic Content Size时才起作用。
优先级
视图可以设置 Compression Resistance和Content Hugging的优先级。自动布局首先会尽力满足各种约束条件,如果在冲突时,根据优先级来决断。例如一行上有两个label,需要的显示宽度为200,那么在ip5上, Compression Resistance优先级高的将被设置为200,另一个可能被设置为100。
使用可视化语言创建约束
一些例子
Inequality, Priority : [wideView(>=60@700)]
Vertical: Flush Views, Equal Heights : V:[redBox][yellowBox(==redBox)]
Combination : H:|-[Find]-[FindNext]-[FindField(>=20)]-|
multiplier的作用
multiplier是乘数因子,会影响属性值的结果。
通过multiplier=1.5,可以设置子试图位于父视图宽度3/4的位置。
通过multiplier=1.618, 可以设置两个视图的宽度比为黄金分割比。
动画实现
使用自动布局在对视图应用动画时,不能在象原来那样直接修改frame的尺寸,应该修改修改视图的约束属性,再调用父视图的[superview layoutIfNeeded]方法。
混用AutoResizeMask和AutoLayout
通过设置视图的translatesAutoresizingMaskIntoConstraints属性为YES,IB会自动把autoResizeMask转化为约束。
1 | [button setTranslatesAutoresizingMaskIntoConstraints:NO]; |
最佳实践
- 在增加约束前,先把View的相对位置安排好,这样增加了约束后,就不会出现约束关系倒置的情况。
- 提前做好视图的分组计划。视图更换容器后,已经添加的约束自动删除,即使是成组移动也是如此。常见情况就是刚开始布局好后发现,视图大小超过了屏幕大小,需要移动到一个UIScrollView里面。
- 把视图分组组织。把一些关系密切的组成一组,添加的一个父视图view里面。然后对父视图进行布局。减少同一层级视图的数量。
- 对辅助视图进行命名,便于识别约束。UIButton、UIButton、UIImageView都会根据现实意义的问题和图片命名,但是UIView默认情况下没有识别符,这时可以给UIView的labal进行命名。
- 选择合适的约束参照物。
Next & Question?
- frame 和alignment size的区别?
###参考文档
WWDC2012 202 – Introduction to Auto Layout for iOS and OS X
WWDC2012 228 – Best Practices for Mastering Auto Layout, 232 – Auto Layout by Example
objc.io系列文章 advanced-auto-layout-toolbox
objc.io系列文章 advanced-auto-layout-toolbox中文翻译