Auto Layout 可以根据加在 view 上的约束条件,动态计算 view 在视图层级中的大小和位置。例如,你可以给一个 button 和一个 image view 设置这样的约束条件:button 与 image view 保持水平居中,并且使 button 的顶部距离 image view 的底部始终保持 8-point 的距离。这样如果 image view 的大小或者位置发生改变,通过 Auto Layout 会重新计算 button 的大小与位置,更新 button 的布局。

外部变化

父视图的大小或者形状发生改变时,会引起外部变化。这时你需要根据父视图的大小去更新界面布局,以达到最好的适配效果。以下一些操作会引起这种变化:

  • 用户调整 window 大小 (OS X).
  • 用户使用 iPad 的分屏功能时 (iOS).
  • 设备屏幕发生旋转 (iOS).
  • 呼入来电,音量条的显示与消失 (iOS).
  • 你想支持不同的屏幕比例,当屏幕等比缩放时会引起外部变化.
  • 你想支持不同的屏幕尺寸,当应用在不同屏幕大小运行时会引起外部变化.

这些操作大部分发生在 APP 运行的时候,因此需要对这些突然的变化做好动态适配。另外,如果你的 APP 进行了屏幕适配,则意味着你的 APP 可以适配各种机型。一个好的屏幕适配方案,可以使你的 APP 在 iPhone 4S,iPhone 6 Plus,甚至 iPad 上做出很好的适配。同时,Auto Layout 也是使 iPad 能够支持多任务和分屏的关键。

内部变化

当视图本身尺寸发生变化或者界面上一些控件发生变化时,会引起内部变化。

一下一些因素会引起内部变化:

  • APP 展示内容发生改变.
  • APP 支持国际化.
  • APP 支持动态字体 (iOS).

当 APP 展示内容发生变化时,有时需要更新布局来重新排版内容。这种场景一般发生在文本类或者图片类的 APP 中。例如一个新闻类的 APP,需要根据新闻内容去自动调整布局。类似的,一个图片类 APP 需要根据图片比例做好自动适配。

所谓的国际化过程,就是将 APP 针对不同语言、地区和文化做好适配。对于一个做了国际化处理的 APP,不同的环境下展示内容可能会不同。因此在进行布局适配时,需要将这些因素考虑进去,使 APP 在不同的环境下可以显示正确的内容。

国际化对布局的影响主要有三个方面。第一,当切换不同的语言时,对应的一些文本框需要的空间不同。例如,想对于英语来说,德语需要更多的空间,而日语需要更少的空间。

第二,不同的国家与地区,虽然使用语言相同,但是日期格式可能会有些不同。尽管这些改变不是很明显,但是仍需要对此做好动态适配。

第三,有时候语言的改变,不仅会影响文本的大小,还有可能影响布局方向。例如,使用英语的国家一般是从左到右的布局,而使用阿拉伯语和希伯来语的国家是从右到左的布局。一般来说,交互设计需要根据用户习惯进行合理布局。一个 button ,在语言为英语时如果放在右下角,那么当语言切换为阿拉伯语它应该放在左下角。

最后,如果你的 APP 支持动态字体,那就代表用户可以修改 APP 字体大小,这会影响文本的宽和高。如果用户改变了 APP 的字体大小,那么布局必须做出相应的适配。

自动布局相对于 Frame 布局

这里有三种主流方式去设计布局。你可以直接通过编码进行布局,也可以使用 autoresizing 布局,或者使用 Auto Layout。

在过去,APP 通过编码设置 view 的 frame 进行布局。以父视图为基础坐标系,frame 定义了 view 的 origin,height 和 width。



在进行布局时,你需要计算每个子 view 的 size 和 position。当有视图位置或大小发生改变时,你需要对受影响的视图重新布局。

在很多时候,虽然使用 frame 布局可以灵活控制 view 的大小与位置。但是相对的,当视图结构发生改变时,你需要花费大量的精力去重新布局。

你可以使用 autoresizing mask 布局来减少工作量。使用 autoresizing mask 可以给 view 和其 superview 设置一些简单约束,当 superview 发生改变时,view 可以动态适配这种改变。

然而,autoresizing mask 只是布局体系中的一个子集。当布局变得复杂时,需要使用代码与 autoresizing mask 配合才能布局。除此之外,autoresizing mask 只能简单适配的外部变化,不能适配内部变化(例如同一层级的其他 view 发生变化时,使用 autoresizing mask 不能做出动态适配)。

autoresizing mask 只是相对于代码布局简单提升,而 Auto Layout 则是一种全新的布局范式。在使用 Auto Layout 对个 view 布局时,不仅会考虑 view 的 frame,还会考虑与之相关的其他 view 的相互作用。

Auto Layout 是通过一系列的约束进行页面布局的。使用约束设置两个 view 的关系之后,Auto Layout 可以根据约束动态计算 view 的大小和位置,这使 view 既可以响应外部变化,又可以响应内部变化。



通过约束对视图进行详细的布局,与以往通过代码处理一些事件相比,在逻辑处理上似乎有很大不同。其实,两者并没有太大的区别。这里有两项基本功要做:首先你要理解约束布局背后的逻辑,其次你要学习如何使用 API。在平时编码过程中,你已经将这些基本功掌握的十分熟练。所以 Auto Loyout 对你来说不再是什么难事。

通过阅读剩余的一些篇章,你会很轻松的掌握 Auto Layout.Auto Layout Without Constraints 章节描述的十分抽象,简化了 Auto Layout 布局过程。Anatomy of a Constraint 章节讲解了 Auto Layout 背后的原理,如果你想更好的掌握 Auto Layout,你需要自己去了解这些原理。Working with Constraints in Interface Builder 讲解了一些用来设计 Auto Layout 的工具,而 Programmatically Creating ConstraintsAuto Layout Cookbook 章节详细讲解了的 Auto Layout 的 API。最后,在 Auto Layout Cookbook 这一篇中,提供了许多的基于 Auto Layout 的样例,你可以学习这些样例,将其中的一些技巧运用到你自己的项目中,Debugging Auto Layout 提供了一些常见问题解决方案和调试工具,当布局出现问题时,你可以参考这些方案或者使用这些工具进行修复。