iOS 开发实践之 Auto Layout

471 阅读4分钟

欢迎大家来我们的交流社区,一起来交流学习,我会定期分享一些我在项目中遇到问题的解决办法和一些iOS实用的技巧,现阶段主要是整理出一些基础的知识记录下来。加微信邀请你加入 15388944845

本文是博主 iOS 开发实践系列中的一篇,主要讲述 iOS 中 Auto Layout(自动布局)在实际项目中的使用。

Auto Layout 在 2012 年的 iOS 6 中发布,距今已经 2 年多了,如果从 2011 年在 Mac OS X 上发布的 Auto Layout 开始算起,已经超过 3 年了。如果你的简历上写着 2 年以上工作经验,而竟然不会使用 Auto Layout,真有点不可思议。

本文将会通过若干个 Demo 进行讲解,通过实践来理解 Auto Layout 到底是什么,该如何使用(包括在 Xib 中使用以及手动编码)。

Auto Layout 是什么?

我的理解:Auto Layout 是一种基于约束的布局系统,它可以根据你在元素(对象)上设置的约束自动调整元素(对象)的位置和大小。

官方的说明:

Auto Layout 是一个系统,可以让你通过创建元素之间关系的数学描述来布局应用程序的用户界面。——《Auto Layout Guide》

Auto Layout 是一种基于约束的,描述性的布局系统。——《Taking Control of Auto Layout in Xcode 5 - WWDC 2013》

这里有几个关键字:

  • 元素

  • 关系

  • 约束

  • 描述

元素(Element)

低头看看你电脑的键盘,你可以把每一个按键当做一个元素;对于 iOS 系统来说,你可以把桌面上每一个应用图标当做一个元素;对于某一款 iOS 应用来说,你可以把视图中的每一个子视图当做一个元素。

事实上,你也可以把整个键盘、桌面或者视图当做一个元素。

关系(Relation)

元素之间可以有关系。例如在键盘上Q 键和W 键之间有关系。是什么关系呢?有很多,例如Q键在W 键的左边,W键在 Q 键的右边,Q键和W键之间相距 0.5 厘米等等。

不理解?试着把键盘想象成View,把按键想象成 Button,再思考一遍。

约束(Constraint)

元素之间关系的限制。约束是 Auto Layout 系统中最重要的概念。我们上面提到的 左边、右边 以及 相距 0.5 厘米 等这些都是约束,它们限制了元素之间的关系。

描述(Description)

定义约束来限制元素之间的关系。描述定义了元素之间的关系及约束。

继续用键盘举例,**Q 键的长宽均为 1 厘米,左边距离键盘的左边缘 10 厘米,上边距离键盘的顶部 5 厘米。**这句话就可以定位 Q 键在键盘中的位置,很轻松就可以计算出 Q 键的 frame 为 {{10.0, 5.0}, {1.0, 1.0}}。

现在 Q 键的坐标已经确定,那么 W 键的坐标可以这样描述:**顶部和 Q 键对齐,大小和 Q 键相等,位于 Q 键右侧 0.5 厘米处。**仔细想想,这句话中包含了元素间的关系,关系间的约束,可以直接计算出 W 键的 frame。

忘掉传统的 Springs & Struts 布局方式

事实上如果你用传统的设置 frame 的布局方式的思维来理解上面的 Q 键和 W 键的布局也说的通。

因为在 Auto Layout 中,当你描述完之后, Auto Layout 会自动帮你计算出 frame。换句话说,你的描述告诉了 Auto Layout 如何帮你计算出 frame。所以,你也可以理解为你间接的设置了 frame。为什么要这么做呢?为什么不直接设置 frame?这是因为使用 Auto Layout 有很多好处:

  • 多数情况下旋转屏幕不用再做额外的处理

  • 更容易适配不同尺寸的屏幕

  • 上手后布局非常简单容易,布局逻辑更清晰

Auto Layout 和传统布局很大的不同之处在于它是一种相对的布局方式。怎么理解这句话?上面提到

W 键位于 Q 键右侧 0.5 厘米处。

传统的布局无法直接表示,你必须把这种布局手动转换为传统布局代码。例如上面的 Q 键和 W 键的传统布局代码看起来可能是这样:

q.frame = CGRectMake(CGRectGetMinX(keyBoard.frame) + 10.f, CGRectGetMinY(keyBoard.frame) + 5.f, 1.f, 1.f);
w.frame = CGRectMake(CGRectGetMaxX(q.frame) + 0.5f, CGRectGetMinY(q.frame), CGRectGetWidth(q.frame), CGRectGetHeight(q.frame));

使用 Auto Layout 的布局代码看起来像这样:

// 伪代码
q.width = 1.f;
q.height = 1.f;
q.left = keyboard.left + 10.f;
q.top = keyboard.top + 5.f;

w.top = q.top;
w.width = q.width;
w.height = q.height;
w.left = q.right + .5f;

Auto Layout 不仅能轻松表示这种布局,而且相对于传统的布局更清晰简洁易懂,还免费附赠很多优点,有什么理由不使用 Auto Layout 呢?

实践中我发现对于很多新手来说,Auto Layout 这种布局方式比较容易理解接受,相反很多对传统布局很熟练的人却不太容易理解,总是用传统布局的思维来思考,所以如果可能的话,我建议你暂时忘掉传统的布局方式