UIStackView提供了一个高效的接口用于平铺一行或一列的视图组合。对于嵌入到StackView的视图,你不用再添加自动布局的约束了。Stack View管理这些子视图的布局,并帮你自动布局约束。也就是说,这些子视图能够适应不同的屏幕尺寸。此外,你可以嵌入一个stack View到另一个stack view中来创建更为复杂的用户界面。不要误解我的意思,这并不意味着你就不需要处理自动布局了。你仍旧要定义一些布局约束来约束stack view。它只是帮你节约了为每个UI元素创建约束的时间,同时它更容易的从布局中添加/删除一个视图。
Xcode7提供两种方式使用UIStackView。你可以从对象库中拖一个Stack View(水平的/竖直的)放到storyboard的正确位置上。然后你可以拖一些label,button,imageView等视图放到stack view中。另外,你可以在自动布局栏中使用Stack选项。对于这个方式,你可以简单的选择两个或更多的视图,之后点击Stack选项,IB将会把这些视图嵌入到一个stackview中,并自动的调整。如果你仍旧对如何使用stack view没有太多头绪,没关系,接下来我们将在这篇文章中介绍这两种方式。继续往下阅读,你就会很快明白我的意思的。
我假设你对auto layout了解。如果不是,请先阅读这片关于autolayout的[介绍文章]
Demo App
先瞧一眼我们将要构建的demo app。在这篇文章中我将会给你展示如何使用stackview布局一个类似的用户界面:
你可以不使用stack view创建一样的UI,但是,但正如你所看到的,stack view完全改变了布局用户界面的方式。本文并没用coding,我们只是集中在使用IB来布局这个用户界面。
开始前,请下载这个[开始项目](备用[自己新建的开始项目])。你需要使用Xcode7 beta4(或以上版本)来build这个工程。如果你没有安装,你要下载个。该项目模板非常简单,它仅仅预置了导航控制器和一些示例图片。
感谢:实例的照片是由[magdeleine.co]提供。
从对象库中添加Stack Views
现在升级Xcode7并打开Main.storyboard。从对象库中拖出垂直的stack view放到storyboard上的view controller中。Stack View可以在纵向和横向布局安排其子视图(称为安排视图)。因为我们要布局垂直的图像视图,所以我们选择垂直的Stack View。
接下来,从对象库中拖出一个图像视图,当你把图像视图放到stack view中,图像视图会自动调整。重复同样的操作,添加更多的image view。这就是它神奇的地方:当您添加另一个图像视图时,stack view会自动布局图像视图,为您设置必要的约束。酷,对吗?
为Stack View定义布局约束
Stack View节省了开发者为每个UI元素定义约束的时间,所说的,您需要提供Stack View的布局约束。对于我们刚刚添加的,我们需要定义以下布局约束:
设置Stack View的距上,距左和居右的间距,使得Stack View在屏幕的顶部。
为Stack View设置一个高度约束,使得Stack View视图的高度占父视图高度的70%。
现在选择stack view,点击布局栏按钮中的Pin按钮,设置距上,距左,居右值分别为10,0,0。然后点击“Add 3 Constraints”按钮添加这些约束。
Stack view的当前位置不符合约束,你可以在Document Outline点击警告指示(即黄色的箭头)纠正位置。
要设置高度约束,就要在IB的Document Outline中从堆栈视图到视图中的控件拖动视图,释放按钮后,选择“Equal Heights”。
这是设置stack view的高度和这个view的高度相等的。然而,stack view仅仅需要高度的75%。所以,选择“Stack View.height”的约束,选择Attributes inspector,把Multiplier这项的值从1.0改为0.7.
设置Stack View的属性
这个stack view 看起来并不是我们期望的。一旦你添加了stack view,你可以改变一些stack view的属性来改变它的外观。axis选项决定是否应布置的视图垂直或水平布置。 alignment选项控制这些视图的对齐方式。比如你如果设置成Leading,stack view管理的视图排列按Leading对齐。
distribution属性决定了其管理的视图的大小和位置。默认设置为Fill。这是stack view尽量让它的所有子视图在一个合理的距离。现在把它改为Fill Equally。stack view会调整它所有的子视图一样的尺寸。
spacing属性让你设置视图之间的间距。把它值改为10来增加图像视图之间的间距。
设置图像
接下来,我们设置image view的相应的图像。选择第一个image view,选择Attributes inspector,把image设置为“nature-1″,把model设置为“Aspect Fill”,同时勾选上“Clip Subviews”。重复同样的步骤设置余下的image view,但是要把image 设置为“nature-2″ 和 “nature-3″。这样你的布局看起来像这样:
现在你可以运行项目,预览下。可以在模拟器上测试app的UI是否正确的适配所有的设备。stack view已经自动的为你添加好了约束。事实上你可以启动view debugging选项(要在运行app的时候)来显示图像视图的布局约束。
使用嵌套Stack View布局标签和按钮
我们还没有完成。有几个标签和按钮添加到用户界面。现在将标签从对象库中拖到视图,命名“Nature”,并将其定位在stack view下面。把它的字体大小改为30点,使其更大一些。下一步,将另一个标签视图和名称标签”A collection of nature photos from magdeleine.co“。放置在Nature标签之下。
再次,您不需要设置这些标签的布局约束。让stack view为你做这个魔术。在本教程的最开始,我提到了使用stack view的方法。之前,是从对象库中添加了堆栈视图。现在我会告诉你另一个办法。
按住命令键来选择标签,然后单击布局栏中的Stack按钮。IB自动把这些标签嵌入到垂直堆叠视图中。
下一步,向视图添加2个按钮。命名一个按钮,“Like”,另一个是“Share”。再次,我们不想处理自动布局。所以,在布局栏中选择按钮,然后单击Stack按钮,将两个按钮嵌入到一个水平堆栈视图中。设置堆栈视图的spacing值为5。
如果你看了最后的布局,这两个按钮应该放在Nature标签旁边。你怎么能做到这一步呢?关于stack view的最重要的是,您可以使用嵌套的多个stack view来构建你想要的精确布局。现在将stack view拖到Nature标签的按钮上。一旦你释放了按钮,stack view将被嵌入到另一个stack view中。布局Nature标签和按钮,选择两种视图,然后将它们添加到另一个stack view中,使用stack选项。默认情况下,新堆栈视图的轴设置为垂直方向。在属性检查中,把它改为水平,这样就可以把Like和Shared按钮放置在Nature标签旁边了。
按钮也需要与Nature标签的基线对齐。选择stack视图,并将alignment从Fill改为First Baseline。同时,spacing选项设置为20,这样来添加Naturel标签和按钮之间的间距。
正如你所看到的,我们只需要使用嵌套的stack view构建你需要的精确布局。
最后,我们为包含图像的stack view和包含按钮&标签的stack view之间的设置布局约束。选择包含按钮和标签的堆栈视图,然后单击布局栏按钮中的Pin按钮。设置居上、距左和居右的值分别为0、8和0。
确保描述标签是自动调整大小,Lines设置为0和Line Breaks设置为Word Wrap。太好了你已经完成了界面设计。现在运行该项目来看看结果。如果您的一切配置正确,您的UI应该看起来像这样:
如果你把iPhone横过来,UI应该是这样:
它看起来不错,但如果这些图像想这样横向排列的话,是不是更给力?
使用Size Classes 调整Stack Views
为了达到iPhone在不同的方向上布局不一样,我们必须使stack view自适应。在iOS 8中,介绍了Size Classes的概念。下表显示了iOS设备及其相应的Size Classes:
你可以使用size classes提供的重写原来的基本布局。在这种情况下,我们在这两种size classes情况下要设置stack view的axis(持有图像视图的)从垂直到水平:
Compact width-Compact height
Regular width-Compact height
现在选择stack view,在选择Attributes inspector。在Axis选项下点击+按钮。选择Any Width > Compact height,之后设置这个size classes下的Axis值为Horizontal。这里,any width包括compact和regular两种宽度。
做完这些,stack view将会在iPhone横屏的时候设置为水平。在不同的iOS设备上运行项目,查看结果。