(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(对齐)



1306450-50e8b172b92030e4.png

本质上来说,使用AutoLayout就是先输入一组约束信息,然后系统会将其转换为一系列的方程,最后通过线性代数算出你想要的frame,并进行视图的布局。



Maintainable Layouts(创建易维护的布局)



1306450-05a7262f524d001e.png

这么多约束!如果,让你在星星控件和Essentials中间加一个控件,你会从哪里开始着手?
找到某些关键的约束,然后去掉,然后再添加新的控件和新的约束???很难受,对吧?

使用UIStackView (iOS 9) 和 NSStackView (OS X 10.9)可以更好地去解决这个问题!
Stack View的实现基于AutoLayout,它会帮你管理约束。


  • 水平、竖直布局方式


    1306450-84b0f2fc71df77bc.png


  • 对齐方式


    1306450-ef75073f46468e1c.png

    1306450-c48f3657b48a8117.png


  • 分布方式


    1306450-c047d7c37144bd2a.png

Fill Proportionally基于subview的ContentSize。




使用Stack View进行布局的效果:

1306450-9acdc2a5939a7e10.png



Changing Constraints (改变约束)



使用Activate和Deactivate,而不是Add和Remove。

  • 约束会找到自己所属的容器;
  • 更高效地添加约束;
  • 你不需要手动地去引用你的View来改变布局;



切记!永远不要对self.view.constraints进行deactivate操作。

  • 不是所有的约束都属于当前view;
  • 会有神奇的事情发生;
  • 一定不要这样做!

如果某个约束需要更改,引用这个约束,稍后更改即可。
如果需要基于约束做动画,就引用这个约束,然后在View的Animation中做动画即可。



View Sizing(View的尺寸)


  • 固有的内容尺寸(Intrinsic content size)
    某些View具有intrinsicContentSize属性,比如:Label和ImageView


    1306450-3770c31596991cd8.png

    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来决定;
  • 约束必须决定高度(充分利用比例关系);
1306450-ab219a9e0797d016.png
shorter text

1306450-c3e82d6b9b9e6713.png
longer text


Priorities(优先级)


Constraint Priorities
1306450-e6381d025c99e63b.png
Constraint Priorities




1306450-ed3b1875f4bf2a7a.png

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

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

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

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



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

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



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

widthConstraint.priority = UILayoutPriorityDefaultHigh + 10;



Content Priorities
1306450-d057c44458f3feb4.png
Content Priorities

Content Priorities的设定,决定了View如何处理它的内容。

Content Priorities默认设定不是Required。

  • 你也不要将它设定为Required级别;
  • 如果设定为Required,可能会导致约束不适用;



1306450-a4fb8fe59ae23c50.png

当然,相同的Content Priorities也可能会导致歧义。


  • Content Hugging Priority


    1306450-c580b59e9c989e2b.png

    1306450-3d263a8978754c82.png

    1306450-3f71c27bb87f9ce2.png

    1306450-9997d7eaea53a03f.png

可以发现,通过更改Content Hugging Priority的值来更改View的布局。
布局的最终结果依赖于View内部的内容。


  • Content Compression Resistance Priority
1306450-d3812d302dc542d2.png

1306450-fc244a449b84906e.png

可以发现,更改Content Compression Resistance Priority的值也会影响View的布局。



总结一下,使用Priority的好处:

  • 可以使约束远离不适用的情况(但是要小心优先级之间的竞争);
  • 布局更加一致;
  • 可以得到正确的布局(Hugging priorities拥抱View的内容,Compression resistance防止被挤压);



Alignment(对齐)


  • firstBaseline 和 lastBaseline
    使用 firstBaseline 和 lastBaseline 比使用 top 和 bottom 更好地实现文本对齐。
    对于动态文本,效果更佳。
1306450-e6990b358e02f21d.png
使用lastBaseline来对齐文本

1306450-232be64d44a59ca8.png
使用firstBaseline来对齐文本


  • Leading and Trailing
使用left/right (英语)使用left/right (阿拉伯语,阅读顺序是从右到左)使用 leading/trailing
1306450-dd9ce109bfec1f36.png
1306450-e3af8e886c15cc6c.png
1306450-4c77bc7778a92ed5.png

使用 leading/trailing 而不是 left/right。
可以更好地实现本地化。


  • Alignment Rects
transform前transform后
1306450-a5c78e3ed8001290.png
1306450-f64000cbad473c49.png
  • Alignment Rects通常不等同于frame
  • 只包含最主要的部分
  • 就算view发生了transform也不会改变。

比如上图中,不包括阴影部分(按钮的阴影),也不包括那些次要的部分(勾的最上面部分)。

如果需要使用Alignment Rects,重写view的alignmentRectInsets属性即可。



可以通过Xcode调试,找到alignmentRectInsets。

1306450-7c3a05d5fec9e69b.png

1306450-e259ec1640ca7335.png

勾选Show Alignment Rectangles之后,点击Capture View Hierarchy,即可看到Alignment Rectangles (黄颜色的矩形)。


1306450-5b4ddcd28a251a60.png

也可以通过alignmentRectForFrame获取。


布局构建概览
1306450-b749d300625c1536.png

1306450-c8463fe1de67d299.png


总结

  • 使用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




转载请注明出处,谢谢~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值