第七频道

探索创新和消费
有料有趣的创业交流平台

窥探iOS可视化编程中AutoLayout的精髓

文/VCC(简书作者)
原文链接:http://www.jianshu.com/p/8c325cee6a78
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

在iOS开发中,使用可视化编程能够简单快速的拖拽出令人满意的UI。但是,除了简单的拖拽之外,还有一项工作对于可视化编程来讲必不可少,那就是AutoLayout自适应布局。因为,没有进行AutoLayout的UI将无法适应屏幕大小不同的机型。本文主要基于Xcode 7.2.1总结一下个人在可视化编程中进行AutoLayout的几点经验,大神请绕过。


本文结构图

一、关于约束

在可视化编程中进行AutoLayout的方法就是添加约束。通过添加合适的约束,使控件能够按照预期的位置和大小显示在屏幕大小不同的机型上,也就实现了AutoLayout自适应布局。

1、添加约束

学习过可视化编程的小猿们应该都知道添加约束的几种主要方法:

方法一:使用 Interface Builder 界面右下角的 Stack 、Align 、Pin 、Resolve Auto Layout Issues 四个约束操作按钮。

方法二:在 Interface Builder 界面上,按住 control 键,从控件开始拖动鼠标到参考控件上,松开鼠标就会弹出约束选择窗口(如图 1-1)。


图 1-1

方法三:在 Interface Builder 界面左侧的 Document Outline 窗口中,按住 control 键,从控件开始拖动鼠标到参考控件上,松开鼠标就会弹出约束选择窗口(如图 1-2)。


图 1-2

 

2、约束分类

从上面的截图中我们可以发现,约束大致上可以分为三类:

2.1  距离约束

距离约束主要用于限定控件相对于参考控件的距离关系。相对于不同的参考控件,距离约束的具体名称会有一些区别,但作用效果基本相同。例如:

相对于根 View 的距离约束为:Leading Space to Container Margin 、Trailing Space to Container Margin 、Vertical Spacing to Top Layout Guide 、Vertical Spacing to Bottom Layout Guide 。

相对于非根 View 的父 View 的距离约束为:Top Space to Container 、Leading Space to Container 、Bottom Space to Container 、Trailing Space to Container 。

相对于无包含关系的其它控件的距离约束为:Horizontal Spacing 、Vertical Spacing 。

2.2  对齐约束

对齐约束主要用于限定控件相对于参考控件的距离关系。同样,相对于不同的参考控件,对齐约束的具体名称也会有一些区别。例如:

相对于跟 View 或父 View 的对齐约束为:Center Horizontally in Container 、Center Vertically in Container 。

相对于无包含关系的其它控件的对齐约束为:Center Horizontally 、Center Vertically 。

2.3  宽高约束

宽高约束主要用于限定控件相对于参考控件的宽高关系,包括:Equal Widths 、Equal Heights 、Aspect Ratio 。

二、窥探精髓

上面讲述了关于约束的基本内容,但具有可视化编程经验的小猿们都清楚,只知道这些基本内容还远不足以添加出能够满足各种 AutoLayout 需求的约束。所以说,接下来我们就深入其中,窥探精髓。

在 Interface Builder 界面中选中某个控件,我们就可以在 右侧 Utilities 窗口 —> Size 选项卡 —> Constraints 选项 下查看已经添加的约束(如图 2-1),并可以点击 Edit 或者双击进入约束详情对这些约束进行编辑。


图 2-1

或者我们可以直接在 Interface Builder 界面选中控件上的具体约束,在 右侧 Utilities 窗口 —> Size 选项卡 下就会显示约束详情(如图 2-2),可直接进行编辑。


图 2-2

约束详情中都包括哪些内容呢?下面我们就来详细了解一下。

在图 2-2 中我们可以看到,约束详情的最上面是约束的名称,也就是图中的 Center X Alignment Constraint ;最下面是一个 Placeholder 选项,内容是 Remove at build time ,从字面意思就可以知道,如果选择了这个选项,编译时将会移除这个约束,所以说一般情况下我们是不会勾选这个选项的;详情中剩余的内容也就是需要重点讲述的内容,其实这些内容都可以用 NSLayoutConstraint 的属性进行描述:

First Item:(id firstItem 属性).(NSLayoutAttribute firstAttribute 属性),其中的 firstAttribute 属性是可选的。

Relation:NSLayoutRelation relation 属性,有三个选项可供选择:Less Than or Equal(<=)、Equal(=)以及 Greater Than or Equal(>=),默认是 Equal(=)。

Second Item:(id secondItem 属性).(NSLayoutAttribute secondAttribute 属性),其中的 secondAttribute 属性是可选的。

Constant:CGFloat constant 属性,常数,可以手动输入,用以对约束进行调整。

Priority:UILayoutPriority priority 属性,优先级,默认值为1000,可以手动输入,一般不做修改。

Multiplier:CGFloat multiplier 属性,系数,可以手动输入,用以对约束进行调整。

Identifier:NSString *identifier 属性,约束标识。

这些内容遵循一个公式来限定约束:

First Item =(<=、>=) Multiplier × Second Item + Constant

这个公式就是约束的精髓,也就是可视化编程 AutoLayout 的精髓。公式中 First Item 的 firstAttribute 属性和 Second Item 的 secondAttribute 属性是可选的,Multiplier 系数和 Constant 常数可以手动输入,所以说我们可以通过编辑约束来随心所欲的修改约束,进而限定控件的位置和大小,实现可视化编程中的各种 AutoLayout 需求。

三、特殊需求

1、Label 的高度自适应

Label 的高度自适应非常简单。具有可视化编程经验的小猿们都知道,给 Label 加约束时不添加宽高约束也不会报错,因为系统默认 Label 的 numberOfLines = 1,height = 20.5,宽度根据文字长短自适应。但有些时候,我们需要使用 Label 显示一段很长的文本,就需要进行高度自适应:添加约束限定 Label 宽度,在 右侧 Utilities 窗口 —> Attributes 选项卡 —> Label 选项 下将 Lines 设置为0。

2、ScrollView 的 AutoLayout

曾经尝试过在可视化编程中对 ScrollView 进行 AutoLayout 的小猿们都知道,如果我们以 ScrollView 作为参考控件给其上的控件添加宽高约束,系统就会报错。怎么办呢?曾经有朋友告诉过我一个使用三方解决的方法,具体是什么三方我不记得了,因为我基本不会用这种方法。

那么我是怎么解决的呢?其实只要清楚问题的根源,我们就可以很简单的解决它。

我们使用代码创建 ScrollView 的时候,都必须要给定它的 contentSize 属性,但是我们在可视化编程时并没有对这一属性进行设置。所以,当我们以 ScrollView 作为参考控件给其上的控件添加宽高约束时,系统自然就会报错。解决问题办法也就是在给 ScrollView 上的控件添加宽高约束时以除 ScrollView 以外的其它控件作为参考控件。

考虑到我们可能会在 ScrollView 上添加很多个控件,最好的作法就是先在 ScrollView 上添加一个空白 View 作为 contentView ,添加好约束后将需要添加的控件添加到 contentView 上,这时就可以按照正常添加约束的方法给这些控件添加约束了。下面的动画演示的是在 ScrollView 上添加一个与根 View 等宽、高度为根 View 高度2倍的 contentView ,并添加约束的过程:


图 3-1

3、TableViewCell 的高度自适应

在实际开发中可能经常会遇到 Cell 的高度要根据显示的文字的多少进行调整的需求,这种情况下,如果我们通过可视化编程来定制 customCell ,又该怎样添加约束来使 customCell 的高度能够自适应呢?

首先,我们要给 customCell 中显示文字的 Label 添加约束:

第一步:限定 Label 的宽度,但不要限定 Label 的高度,因为 Label 高度自适应之后 customCell 才能高度自适应;

第二步:通过 Leading Space 或 Trailing Space 或 Center.X 限定 Label 在水平方向上的位置;

第三步:限定 Label 的 Top Space 和 Bottom Space 两个距离约束;

第四步:在 右侧 Utilities 窗口 —> Attributes 选项卡 —> Label 选项 下将 Lines 设置为0。

然后,我们要在代码中设置 TableView 的 estimatedRowHeight 和 rowHeight 属性:

self.tableView.estimatedRowHeight = 30 ;     // 设置 customCell 的估计高度

self.tableView.rowHeight = UITableViewAutomaticDimension;     // 设置 customCell 自适应高度

这样,我们就实现了 TableViewCell 的高度自适应。

四、实例演示

接下来根据实际开发中的一个 AutoLayout 需求,来给大家做一个小小的演示。之前一个朋友给提了一个 AutoLayout 的需求,具体的 UI 效果如图 4-1,要求三个 ImageView 等宽等高,之间的两个间隔和屏幕边缘的两个间隔宽度相等。朋友告诉我说他是在四个间隔区域使用了四个空白的占位 View ,然后再添加如下约束:

1、添加距离约束:限定两边的空白 View 与屏幕边缘的距离为0,限定四个占位 View 与三个 ImageView 两两之间的距离为0;

2、添加对齐约束:限定四个占位 View 和三个 ImageView 相对于根 View 竖直居中;

3、添加宽高约束:限定四个占位 View 和三个 ImageView 的高度均为 0.2 × 屏幕高度,限定四个占位 View 的宽度均为 0.07 × 屏幕宽度,限定三个 ImageView 的宽度均为 0.24 × 屏幕宽度。


图 4-1

如果试着把这些约束添加一遍,就会发现这种方法非常麻烦,还容易出错。但是,这篇文章读到这里,我们已经完全没必要再使用这种浪费空白占位 View 又非常麻烦的方法了。我们完全可以只对三个 ImageView 添加约束来实现图 4-1中的 UI 效果。计算 Multiplier 系数的过程请自行脑补,下面只演示添加约束的过程:


图 4-2

Notes:

1、衷于分享,欢迎转载;

2、博主才疏学浅,敬请批评指正;

3、如果对您有所帮助,我倍感荣幸,也请您点个赞。

未经允许不得转载:移动技术 > 窥探iOS可视化编程中AutoLayout的精髓

相关推荐

评论