内容概览:
- Maintainable Layouts(创建易维护的布局)
- Changing Constraints(改变约束)
- View Sizing(View的尺寸)
- Self-Sizing Table View Cells(尺寸自适应的TableViewCell)
- Priorities(优先级)
- Alignment(对齐)
本质上来说,使用AutoLayout就是先输入一组约束信息,然后系统会将其转换为一系列的方程,最后通过线性代数算出你想要的frame,并进行视图的布局。
Maintainable Layouts(创建易维护的布局)
这么多约束!如果,让你在星星控件和Essentials中间加一个控件,你会从哪里开始着手?
找到某些关键的约束,然后去掉,然后再添加新的控件和新的约束???很难受,对吧?
使用UIStackView (iOS 9) 和 NSStackView (OS X 10.9)可以更好地去解决这个问题!
Stack View的实现基于AutoLayout,它会帮你管理约束。
-
水平、竖直布局方式
-
对齐方式
-
分布方式
Fill Proportionally基于subview的ContentSize。
使用Stack View进行布局的效果:
Changing Constraints (改变约束)
使用Activate和Deactivate,而不是Add和Remove。
- 约束会找到自己所属的容器;
- 更高效地添加约束;
- 你不需要手动地去引用你的View来改变布局;
切记!永远不要对self.view.constraints进行deactivate操作。
- 不是所有的约束都属于当前view;
- 会有神奇的事情发生;
- 一定不要这样做!
如果某个约束需要更改,引用这个约束,稍后更改即可。
如果需要基于约束做动画,就引用这个约束,然后在View的Animation中做动画即可。
View Sizing(View的尺寸)
-
固有的内容尺寸(Intrinsic content size)
某些View具有intrinsicContentSize属性,比如:Label和ImageView
Size来源于内部的内容(Content)。
系统会决定Size的约束。
布局的Size是没有保证的,因为约束自适应会导致变形。
- 定义明确的Size(Defining a particular view size)
首先,使用约束。
如果有需要,也可以重写intrinsicContentSize属性。比如:- 你无法从约束中获得Size的信息;
- view需要绘制自定义的内容;
- 你需要自己把控约束,比如:本地化文本会有不同的文本长度,需要重新计算intrinsicContentSize;
Size Class的变更也会影响到size。
Self-Sizing Table View Cells(尺寸自适应的TableViewCell)
- 尺寸的自适应依赖于约束;
- 宽度由Cell来决定;
- 约束必须决定高度(充分利用比例关系);
Priorities(优先级)
Constraint Priorities
本该出现在虚线框位置的View,却出现在了错误的位置,为什么?
因为,出现了不只一种布局方案:
- 约束设置不到位
- 约束的优先级设定有误
最终,系统会自行选择布局方案。
约束优先级的值可以设置为1到1000之间的任意值。
- Required 为 1000
- DefaultHigh 为 750
- DefaultLow 为 250
你也可以通过代码来更改约束的优先级:
widthConstraint.priority = UILayoutPriorityDefaultHigh + 10;
Content Priorities
Content Priorities的设定,决定了View如何处理它的内容。
Content Priorities默认设定不是Required。
- 你也不要将它设定为Required级别;
- 如果设定为Required,可能会导致约束不适用;
当然,相同的Content Priorities也可能会导致歧义。
-
Content Hugging Priority
可以发现,通过更改Content Hugging Priority的值来更改View的布局。
布局的最终结果依赖于View内部的内容。
- Content Compression Resistance Priority
可以发现,更改Content Compression Resistance Priority的值也会影响View的布局。
总结一下,使用Priority的好处:
- 可以使约束远离不适用的情况(但是要小心优先级之间的竞争);
- 布局更加一致;
- 可以得到正确的布局(Hugging priorities拥抱View的内容,Compression resistance防止被挤压);
Alignment(对齐)
- firstBaseline 和 lastBaseline
使用 firstBaseline 和 lastBaseline 比使用 top 和 bottom 更好地实现文本对齐。
对于动态文本,效果更佳。
- Leading and Trailing
使用left/right (英语) | 使用left/right (阿拉伯语,阅读顺序是从右到左) | 使用 leading/trailing |
---|---|---|
|
|
|
使用 leading/trailing 而不是 left/right。
可以更好地实现本地化。
- Alignment Rects
transform前 | transform后 |
---|---|
|
|
- Alignment Rects通常不等同于frame
- 只包含最主要的部分
- 就算view发生了transform也不会改变。
比如上图中,不包括阴影部分(按钮的阴影),也不包括那些次要的部分(勾的最上面部分)。
如果需要使用Alignment Rects,重写view的alignmentRectInsets属性即可。
可以通过Xcode调试,找到alignmentRectInsets。
勾选Show Alignment Rectangles之后,点击Capture View Hierarchy,即可看到Alignment Rectangles (黄颜色的矩形)。
也可以通过alignmentRectForFrame获取。
布局构建概览
总结
- 使用Stack View帮助构建易维护的布局;
- 使用activate和deactivate控制约束;
- 用约束决定size(明智地重写intrinsicContentSize);
- 使用Priority合理地解决布局问题;
- 除了使用top, bottom, center进行布局,还可以使用baseline, leading, trailing等(记得做本地化适配);
继续阅读 (WWDC) Mysteries of Auto Layout, Part 2 。
参考文章:
Mysteries of Auto Layout, Part 1
转载请注明出处,谢谢~