Understanding Auto Layout - acaec/Auto-Layout-Guide GitHub Wiki

理解自动布局

自动布局能够基于你所给予视图的约束条件,动态地计算在你的视图结构中的所有视图的大小和位置。举个例子,你可以给一个按钮增添一个约束,令它相对于一个图形视图水平居中,并且这个按钮的顶部边缘总是低于该图形的底部8个点位。如果这个图形的大小或者位置发生改变,则这个按钮的位置也会自动的做出相应的调整来匹配约束条件。

这一基于约束的设计方法允许你建立一个能够动态的响应内部和外部变化的用户界面。

外部变化

外部变化主要产生在你的总体视图的大小和形状发生变化时。对于每一项变化,你必须响应地更新你的视图结构的布局以便最大限度地利用可用的空间。以下是一些常见的外部变化的来源:

用户调整了窗口(OS X)

用户在iPad上进入或者离开了Split View(IOS)

设备旋转(IOS)

来电呼叫或是录音棒的出现与消失(IOS)

你想要支持不同大小的类

你想要支持不同的屏幕大小

大部分的这些变化可能在运行时出现,并且他们需要一个来自你的app的动态回应。其他的一些,像是对于不同大小的屏幕的支持,代表了app对于不同环境的适应能力。尽管屏幕的大小一般不会在运行时改变,但创建一个自适应的界面会使你的app不管是在iPhone 4S上,iPhone 6 Plus上,甚至是iPad上,都能运行的一样出色。自动布局功能同样也是一个帮助支持iPad上Slide Over和Split Views功能的关键组成部分。

内部变化

内部变化主要产生在你的用户界面上的视图或者控制组件的大小发生变化时。

以下是一些常见的内部变化:

随着app的变化,呈现内容的变化。

这个app支持国际化。

这个app支持Dynamic Type(动态字体)(IOS)

当你的app内容出现变化时,新内容可能会需要一种和旧内容不同的布局方式。这种情况在那些给我们呈现文本或者图片的app中很常见。举个例子,一个新闻app需要基于单独的新闻文章的大小进行布局上的调整。相似的,照片拼贴软件必须能够处理大量的不同大小和宽高比的图片。 国际化对于布局有三个主要影响。首先,当你将你的用户界面翻译成一种不同的语言的时候,标签会需要不同大小的空间。例如相对英语而言,德语一般会需要更加多的空间;而日语则通常需要很少的空间。

第二点,即使使用的语言相同,表示日期和数字的形式在不同的地区也可能会是各不相同。虽然这些变化一般相较语言更加微小,但用户界面仍然需要能够适应大小上的微小变化。

第三点,语言的改变不仅会影响文本的长短,同时也会影响界面布局的组织。不同的语言使用不同的布局方向。例如,英语使用从左到右的布局方向,而阿拉伯语和希伯来语则使用从右向左的布局方向。总体上来说,用户界面元素的顺序应该与布局方向相匹配。如果一个按钮对于英语视图来说在右下角,则在阿拉伯语的视图中它应该在左下角。

最后,如果你的IOS app支持动态字体,用户便能够改变你的app使用的字体的大小。这会同时改变你的用户界面中任意文本元素的高宽。如果用户在你的app正在运行时改变了字体大小,字体和布局都必须同时做出调整。

自动布局vs基于框架的布局

有三种主要的方法可以用于用户界面的布局。你可以以编程方式来布局,你也可以使用autoresizing masks这一属性来使其对外部变化自动做出回应,或者你可以使用自动布局。

传统上,app会通过编程来为视图结构中的每个视图设置框架来为它们的用户界面布局。这些框架定义了视图在总体视图的坐标系中的起点,高度和宽度。

为了编排你的用户界面的布局,你需要计算你的视图结构中每一个视图的大小和位置。然后,如果产生了一个变化,你需要为每个受影响的视图重新计算框架。

在许多方面,以编程方式定义一个视图的框架提供了最好的灵活性和功能。当产生一个变化时,你可以逐个的做出你想要的改变。但是因为你必须自己同时管理所有的变化,仅仅是编排一个简单的用户界面的布局就需要相当的功夫去设计、调试和维护。创建一个真正自适应的用户界面增加了一个数量级的困难。

你可以使用autoresizing masks来帮助你减少花在这上面的功夫。一个autoresizing mask定义了视图框架在它的总体视图框架改变时是怎样变化的。这简化了能够自动适应外部变化的布局的创建。

然而,autoresizing masks仅支持可能的布局的一个相对较少的子集。对于复杂的用户界面,你一般会需要对你自己的编程变化增加autoresizing masks。另外,autoresizing masks仅仅能适应外部变化,并不支持内部变化。

尽管autoresizing masks只是一个对于编程布局的迭代改进,但是自动布局却代表了一个完全崭新的范例。你需要考虑的是关系,而不是视图框架。 自动布局使用了一系列的约束来定义你的用户界面。约束一般是代表了两个视图之间的关系。自动布局然后会基于这些约束来计算每个视图的大小和位置。这提供给了布局动态的相应内部和外部变化的能力。

用于设计一系列的用来创建具体的行为的约束的逻辑和写过程式和面向对象的代码的逻辑是很不相同的。幸运的是,熟练掌握自动布局和熟练掌握其它编程任务并没什么两样。有两个基本的步骤:第一你需要理解在基于约束的布局背后的逻辑,然后你需要学习有关API。你已经在学习其它的编程任务时成功地实现了这些步骤,自动布局也不例外。

关于这篇指导的剩余部分是用来帮助你的,使你能够较为轻松地度过自动布局的过渡过程。无约束的自动布局章节描述了一个高级的抽象,用于简化自动布局支持的用户界面的创建。约束的分析章节提供了你需要理解的帮助你成功地独立与自动布局互动背景理论知识。在界面创建中与约束一起工作章节描述了设计自动布局的工具,以编程方式创建约束和自动布局参考章节则细致的描述了相关API。最后,自动布局参考章节呈现了许多不同级别和不同复杂度的样例布局,你可以学习并且在你自己的项目中加以使用,而且如果出现什么问题的话,自动布局的调试章节也提供了一些建议和工具用来帮助你修正。