UIStackView教程
这是一篇挺老的文章,主要就是介绍在iOS9
时推出的控件UIStackView
。我发现网上的资料并不算多,而AppCoda
的这一篇就浅显易懂,所以决定翻译一下,再写个Demo
。
Demo 地址如下 : https://github.com/liberalisman/StackView-Demo
![](https://img.haomeiwen.com/i656733/749cf1cde900924a.png)
UIStackView 简介
开始这个教程的话,我们会讲一些iOS9
的新特性,iOS
最近推出的新版本带来了很多新的特性,而新推出的UIStackView
应该引起开发者第一时间的关注。据我所知,一些开发者认为使用AutoLayout
去设计一些复杂的用户界面是十分困难的。UIStackView
就是帮助开发者将这些复杂页面的设计工作变得更简单。
UIStackView
为布局一组控件提供了线性的布局页面,这组控件可以垂直显示,也可以水平显示。当View
被加入到UIStackView
,你不再需要为它设置约束。UIStackView
会自动管理子控件的布局并为他们添加约束。这也就意味着,子控件可以去适应不同的屏幕尺寸。
再进一步讲,你可以将一个UIStackView
放进另一个UIStackView
中以实现更为复杂的用户界面的设计工作。当然千万不要被我误导,UIStackView
并不意味着你再也不必和约束打交道,你至少是要为UIStackView
设置约束的。UIStackView
只是节省了你为每一个界面元素添加约束的时间,同时你在UIStackView
中添加和删除约束将变得超级简单。
Xcode 7
提供了两种方式去使用UIStackView
。你可以在对象库
拖一个UIStackView
然后放进StoryBoard
中,UIStackView
有水平和垂直两种,然后你可以拖拽一些视图控件,例如Label
,Button
,image
等直接放入UIStackView
。或者,你也可以利用在自动布局工具栏中Stack
选项。利用这种方法,你可以选择两个或者多个视图控件,直接点击Stack
。Interface Builder
会将这些试图对象加入到UIStackView
并且重新指定他们的大小。说到此处如果你还没有明白UIStackView
,那也不要担心。在这个教程中,我们会展示这两种方法。只需要继续阅读,然后在一瞬间,你会 怦 的一下就懂了。
The Demo App
首先我们要预览一下我们即将构建的App,在这个教程中,我们会展示在Interface
中利用UIStackView
如何构建这个App。
![](https://img.haomeiwen.com/i656733/92f10a2cdaa27753.png)
当然你不用UIStackView
也可以构建一个这样的页面,但是正如你所见,UIStackView
完全改变了你进行页面布局的方式。这个教程无需任何代码,我们将专注于利用Interface Builder
来构建这个用户界面。
添加 UIStackView
打开 Xcode 7
,然后打开main.storyBoard
。从右侧的对象库面板中,往storyBoard
中拖一个垂直方向的UIStackView
。UIStackView
可以分别管理水平方向和垂直方向的子控件。因为我们想要布局的ImageViews
是垂直方向的,所以我们选择一个垂直方向的UIStackView
。
![](https://img.haomeiwen.com/i656733/05376537e3636a28.png)
接下来从控件库往外拖一个Imageview
,当你把Imageview
拖拽到StackView
里,Imageview
会自动调整尺寸,重复上面的步骤,我们再往StackView
里面添加两个imageView
,这时候神奇的一幕发生了,当你把另外两个imageView
添加到StackView
里面时,StackView
会自动给这两个imageView
进行垂直布局,并为他们添加上了约束条件。是不是很酷?
为 UIStackView 添加约束
StackView
为开发者节省了为每一个界面元素添加约束的时间,但是你必须要为你的StackView
添加约束条件,接下来我们将为刚才添加到是图中的StackView
添加约束
- 设置
StackView
与父控件顶部、左侧、右侧的距离 - 设置
StackView
的高度占父控件高度的70%
现在,我们选中StackView
并点击Pin
按钮。设置距离顶部、左侧、右侧的距离各自分别为10,0,0。并且把这三个约束加上。
![](https://img.haomeiwen.com/i656733/9c41329601e69786.png)
现在StackView
的位置,并不满足我们的约束条件,你需要点击警告去修复这个问题。
想设置高度的约束,到文档大纲视图。按住Control
键,从StackView
拖线到View
上面,松开后,选择Equal Height
.
![](https://img.haomeiwen.com/i656733/4f5c0fbf39cc7d55.png)
这样设置以后,StackView
的高度就与使徒的View
相等。然而我们只需要让StackView
的高度是视图的View
的70%。所以选择StackView
的Height
属性,然后到属性面板
,把Mutiplier
的值从1.0
变成0.7
。
![](https://img.haomeiwen.com/i656733/b1229e7c50cca716.png)
设置StackView属性值
StackView
看起来并没有像预期一样,一旦你使用了StackView
,你可以通过修改StackView
的属性值来改变它的外观。
Axis
是坐标轴,负责水平还是垂直。
alignment
是对齐方式。
![](https://img.haomeiwen.com/i656733/171279edfacd09b2.png)
Distribution
决定了StackView
中子控件的尺寸和位置。它默认被设置为Fill
。在这个例子里,StackView
要尽可能的利用有限的空间去适配它的子控件。接下来我们将选项改为Fill Equally
。StackView
会自动将里面的子控件重新布局为大小相等的控件。
![](https://img.haomeiwen.com/i656733/46e1b1dd4dba5f53.png)
Space
选项允许你通过修改该选项,调解两个控件之间的距离,此处将值改为10。
![](https://img.haomeiwen.com/i656733/f709506ba851975e.png)
设置图片
接下来为三个ImageView
设置图片
![](https://img.haomeiwen.com/i656733/039abdfb74ad2482.png)
现在可以把程序跑起来看看效果,在不同的模拟器,UI都可以很好的适配各种设备。StackView
已经自动帮你添加好了布局。实际上你可以通过页面调试
选项,来查看为ImageView
添加的布局。
![](https://img.haomeiwen.com/i656733/a61ac78986918daf.png)
用嵌套的方式布局控件
还有一些Lable
和Button
需要添加到页面上,如图所示,拖两个Lable
到StackView
的正下方,上面的标签字号为30.
然后选中两个Lable
,点击stack
选项,将这两个控件合并为一个StackView
。
![](https://img.haomeiwen.com/i656733/2fc3c9c2cfde4233.gif)
接下来添加两个按钮,一个Like
,一个Share
。把这两个控件合并为一个StackView
,设置间距为 5,方向水平。
![](https://img.haomeiwen.com/i656733/73ff343c1735e5f5.png)
把按钮的StackView
拖进Label
的StackView
中,选中顶部的Nature
标签和Button
de StackView
,点击stack
选项,将他们两个合并为一个StackView
,设置方向为水平
![](https://img.haomeiwen.com/i656733/824bec617d41a2a8.gif)
选中这个StackView
,将对齐方式调整为First BaseLine
,沿第一个对象的基线对齐,然后给Lable
和Button
加一个20的间距。
![](https://img.haomeiwen.com/i656733/69dcf16c39e0e804.png)
这样,我们只需要利用 StackView
的嵌套,就可以实现我们想得到的布局。
最后,我们实现了用StackView
包裹ImageView
,同时也实现了StackView
包裹Label
和Button
。将顶部、左侧、右侧各自设置值为 8,0,0。
![](https://img.haomeiwen.com/i656733/ae0d35fcc0620f1c.png)
为了确保Label
的描述文字可以正好适配,将Label
的行数改为0,文字的Line break
设置为文字包裹。这样你就完成了界面的设计。
现在可以把程序跑起来看一下效果
![](https://img.haomeiwen.com/i656733/a8812f51628a29e5.png)
如果横屏,效果是这样的:
![](https://img.haomeiwen.com/i656733/23eedb96316e1519.png)
看起来还可以,但是如果横屏时图片是水平排列那就更好了:
![](https://img.haomeiwen.com/i656733/94febb73d26c308a.png)
利用*Size Class 构建自适应的 StackView
为了实现 iPhone
在横屏时显示不同的布局,我们需要让StackView
是自适应。在 iOS8
,介绍过 Size Class
的概念,下面的表格介绍了不同的 iOS
设备以及他们相对应的 Size Class
。
![](https://img.haomeiwen.com/i656733/bfc014016162a621.png)
你可以利用 Size Class
提供一个指定的布局去覆写之前的布局设计。在这个例子中,我们需要将StackView
的方向在以下两种情况下,由垂直变为水平。
- 宽度紧凑 - 高度紧凑
- 宽度宽松 - 高度紧凑
接下来选择我们的StackView
,然后打开属性面板
,点击Axis
边上的+
号。
选择 任意宽度
, 高度紧凑
,并把StackView
的方向设置为水平方向
。
![](https://img.haomeiwen.com/i656733/2c0aa5021e970b8d.gif)
然后。。。。。。就妥了!
总结
在这个教程中,对StackView
进行了简单介绍,为大家做了一个Demo,以及如何使用这个全新的组件。StackView
这种流线型的布局方式,让你在布局时只需要使用很少的约束。
Apple的工程师也是推荐优先使用StackView
,实在不行在用原生的约束。
我自己做了一个简单的Demo,地址如下 : https://github.com/liberalisman/StackView-Demo