Apple 近几年来推出了各种屏幕尺寸的 iPhone、iPad,以前只在 Android 上存在的不同屏幕尺寸的 UI 适配问题在 iOS 上也日益突出。为了解决这个问题,Apple 为开发者提供了 AutoLayout。区别于以往的手动计算 frame 的方式,AutoLayout 让开发者只需要通过设置约束(constraints)来描述需要什么样的布局,而不是如何进行布局。约束是用来描述一个 view 的布局条件或者两个 view 之间布局关系的对象。通过这种方式有效地减少了适配不同屏幕尺寸的工作量。

    常见的约束包括:长度、宽度、长宽比、两个 view 的间距、对齐方式等,非常简单直观。设置方法可以参考 Apple 文档

    它们的本质是下面的公式:

    view1.attribute1 = multiplier * view2.attribute2 + constant

    系统需要计算各个 view 的位置、大小,也就是 x, y, width, height 四个未知数。系统现在有一些已有的值,比如 root view 的大小、intrinsic size 等,你要做的是提供足够多而又不冲突的这些未知数的关系和一些常量,使得系统能够通过一个多元一次方程组来解出每个未知数。

    几个值得注意的点:

    • 优先级

    约束是有优先级的(1 到 1000),当两个条件冲突时系统会优先满足优先级高的约束。约束可以用来描述不相等的关系(大于等于、小于等于),通常配合优先级使用。

    • Intrinsic Size

    对于某些 view(如 UILabel、UIButton),系统可以自动根据其内容来计算合适的大小,这个大小就叫 Intrinsic Size。对于这种 view,我们可以只设置能确定其位置的约束,而不用指定宽度和高度的约束。对于不支持 Intrinsic Size 的 view,也可以通过重写 intrinsicContentSize 方法来支持 Intrinsic Size。

    • Content Hugging Priority

    简单来说就是相对于 Intrinsic Size 抗拒拉伸的优先级,默认值是 250。如果存在一个约束计算出的 size 比 Intrinsic Size 要大,并且这个约束的优先级比 250 大,则最终尺寸按照这个约束来计算;如果这个约束的优先级比 250 小,则最终尺寸是 Intrinsic Size。

    • Compression Resistance Priority

    相反的,Compression Resistance Priority 是相对于 Intrinsic Size 抗拒压缩的优先级,默认值是 750。

    此外,Apple 提供了两种方式来让开发者设置约束:Interface Builder 和代码方式。为了让用户「更方便地」使用代码来设置约束,苹果还特意发明了一种叫 VFL 的语言,但实际使用起来十分糟糕。如果希望使用代码的方式来设置约束可以试试一个第三方的开源库 Masonry