(WWDC) Auto Layout 的秘密, Part 1


内容概览:
  1. Maintainable Layouts(创建易维护的布局)
  2. Changing Constraints(改变约束)
  3. View Sizing(View的尺寸)
  4. Self-Sizing Table View Cells(尺寸自适应的TableViewCell)
  5. Priorities(优先级)
  6. 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属性。比如:
    1. 你无法从约束中获得Size的信息;
    2. view需要绘制自定义的内容;
    3. 你需要自己把控约束,比如:本地化文本会有不同的文本长度,需要重新计算intrinsicContentSize;

Size Class的变更也会影响到size。


Self-Sizing Table View Cells(尺寸自适应的TableViewCell)


  • 尺寸的自适应依赖于约束;
  • 宽度由Cell来决定;
  • 约束必须决定高度(充分利用比例关系);
shorter text

longer text


Priorities(优先级)


Constraint Priorities
Constraint Priorities





本该出现在虚线框位置的View,却出现在了错误的位置,为什么?

因为,出现了不只一种布局方案:

  • 约束设置不到位
  • 约束的优先级设定有误

最终,系统会自行选择布局方案。



约束优先级的值可以设置为1到1000之间的任意值。

  • Required 为 1000
  • DefaultHigh 为 750
  • DefaultLow 为 250



你也可以通过代码来更改约束的优先级:

widthConstraint.priority = UILayoutPriorityDefaultHigh + 10;



Content Priorities
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 更好地实现文本对齐。
    对于动态文本,效果更佳。
使用lastBaseline来对齐文本

使用firstBaseline来对齐文本


  • 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




转载请注明出处,谢谢~

你可能感兴趣的:((WWDC) Auto Layout 的秘密, Part 1)