To the user,the interface is the product.
-
Aza Raskin
iOS9带来了许多新的特性来让我们的开发生涯更简单,Stack Views的简介就是一个很好的例子.之前给你们简单的介绍了auto layout.这个例子让我们工作起来很简单.但是,随着你的app UI变得更复杂,你会发现给所有的iOS设备完美的提供界面约束变得更难.这是苹果在最新的Xcode和Ios版本中介绍Stack views的一个原因.
这一章,我们将继续讨论界面编辑器里的UI设计.我会教你们怎么来构建一个更全面的界面,你可能会在实际运用中遇到的应用.你将学到如何:
使用堆栈视图来布局用户界面.
使用图片视图来显示图片.
使用内置目录来管理图片.
使用Size类调整堆栈视图.
我们将根据上面的来讨论更多的关于自动布局的内容.你可能会被吓到,因为你一行代码都没写却可以干那么多的事.
堆栈视图(Stack Views)是什么
先说重要的,什么是堆栈视图?堆栈视图提供一个流线型的界面来把视图集合放置成一行或者一列.在Keynote或者PPT里,你可以把很多对象一起分组,那样它们可以作为一个单独对象移动或分组.堆栈视图提供了一个非常相似的特性.你可以用堆栈视图将很多UI对象合成一个.最好的是,视图嵌入一个堆栈视图里以后,你不再需要定义自动布局约束.
视图嵌入一个堆栈视图里时,他们通常被看做安排好的视图.
堆栈视图管理它子视图的布局,然后自动为你提供布局约束.这意味着子视图已经准备好去适应不同的屏幕尺寸.此外,你可以嵌入一个堆栈视图到另一个堆栈视图来构建更复杂的用户界面.听起来很酷,对吗?
不要误解我.这并不意味着你行不需要处理自动布局.你仍然需要定义堆栈视图的布局.它仅仅能够节约你在创作每个UI元素的约束的时间,然后轻松的从布局里来添加/移除视图.
Xcode7提供两个来使用堆栈视图.你可以从对象库里抓起一个堆栈视图(水平/垂直),然后放进storyboard里.然后你可以拖放视图对象如labels,buttons,image views到堆栈视图.另一个办法,你可以用自动布局栏里的Stack选项.用这个方法,你可以简单的选择两个或者更多的视图对象,然后选择Stack选项.界面编辑器将会嵌入这些对象到一个堆栈视图,然后自动重新调整大小.如果你对于怎么使用一个堆栈视图没有头绪,不要担心.这章我们会继续讲解这两个方法.继续阅读,一会你就会知道我的意思了.
简单的app
来看看我们将要构建的demo app.我将展示给你们怎样用堆栈视图来布局一个下面这样的用户界面:
如果你不用堆栈视图,你也可以制作同样的UI.但是就像你希望看到的那样,堆栈视图完全改变了你布局用户界面的方法.再说一次,这章没有代码.
创建一个新的工程
现在关掉Xcode然后创建一个新的Xcode工程.选择Application(iOS下)>"Single View Application"点击"Next".你可以像下面这样简单的填写工程信息:
Product Name:StackViewDemo - 这是你的工程名字.
Organization Name:AppCoda - 这是你公司的名字
Organization Identifier: com.appcoda - 事实上这个域名写反了.如果你有一个域名,你可以用你自己的域名*名字.否则,你可以用"com.appcoda"或者就填"edu.self".
Bundle Identifier: com.appcoda.StackViewDemo - 这是你app唯一的标志,用于提交app.你不需要填这个选项.Xcode会自动帮你生成.
language:Swift - 我们将用Swift来开发这个工程.
Devices: Universal - 选择"Universal".通用app是为iPhone,iPod touch,和ipad设备优化过的单独app.在这个demo,我们将设计一个用户界面能运行在所有的设备上.
Use Core Data:[unchecked] - 不要选择这个.这个简单工程用不到Core Data.
Include Unit Tests:[unchecked] - 不要选择这个.这个简单工程用不到单元测试.
Include UI Tests:[unchecked] - 不要选择这个.这个简单工程用不到UI测试.
点击"Next".Xcode会问你准备把StackViewDemo工程保存在哪里.在你的mac上选择一个文件夹.点击"Create".
添加图片到Xcode工程
像你看到的那样,这个样本app包含3张图片.问题来了,怎样才能在Xcode工程里绑定图片?
在每个Xcode工程,它包括一个asset目录(如Assets.xcassets)来管理图片和图标,这些会在你的app里用到.选择Assets.xcassets文件夹.默认情况下,里面是空的,只有一个空白的AppIcon设置.我们在这章不准备讨论app图标,但是在我们构建了一个真正的app以后我们会说到它.
现在下载这些图片设置然后解压到你的Mac上.压缩包里包含总共9张图片文件,但是它实际上包含3个不同的t-shirt图片.他们每一个都有3个不同的分辨率.这里有个例子:
t-shirt-1.png
t-shirt-1@2x.png
t-shirt-1@3x.png
当开发一个iOS app时,建议一章图片准备3个版本.一个用@3x后缀,这个有最高的分辨率,用于iPhone 6 Plus.一个用@2x后缀,用于iPhone4/4s/5/5s/6,没有@后缀是为非Retina屏幕用的.
添加这些图片到asset目录,你所要做的就是从Finder里拖拽图片到设置列表
一旦你添加了图片到asset目录,图片会自动设置.之后,如果要用这些图片,你只要用一个特殊的名字(如t-shirt-1).你不需要担心要用哪个版本(@2x/@3x).这些iOS都会帮你处理好.
用Stack Views布局标题标签
现在你已经在工程中绑定好了必要的图片,我们来看看堆栈视图.首先,打开Main.storyboard.我们从这两个词开始.
堆栈视图可以在垂直方向和水平方向安排多个视图布局.所以首先,你需要决定你是否想要使用一个水平或者垂直的视图.标题和副标题都被排成垂直的.显然,我们将用一个垂直的堆栈视图.
从对象库里拉一个Vertical Stack View对象到storyboard里的view controller.
接下来,从对象库里拉一个label放进堆栈视图里.堆栈视图会自动嵌入label,调整它的大小.双击label然后把标题改成"Wardrobe".在Attributes inspector里,把字体大小改成50.
编辑新标签的标题然后改成"Keep your wardrobe organized".
一般来说,"Wardrobe"标签是左对齐的.一旦有stack view,你可以批量改变很多stack view的属性来改变它的显示形式.选择stack view然后你会发现它在Attributes inspector里的属性.
顺便说一声,如果你选择堆栈视图有问题,你可以按住shift键然后右击stack view.界面编辑器会显示一个快捷菜单来让你选择.
我们简要讨论一下stack view的每个属性.axis选项表明视图要水平还是垂直布局.把它从vertical变成horizontal,你可以把现有的stack view变成垂直的stack view.alignment选项控制视图怎样对齐.例如,如果它设置成Leading,stack view会边缘对齐(如左对齐).distribution选项定义视图的大小和位置.默认情况下设置成Fill.在这个例子里,stack view视图填满子视图的所有可用空间.如果设置成Fill Equally,垂直stack view会沿着垂直轴线平分两个标签.下图显示了一些不同属性布局的例子.
在我们的demo中,仅仅需要改变alignment选项从Fill到Center,把两个标签居中.去下一节之前,确保你的stack view的位置是正确的.你可以选择stack view去到Size inspector.确保你设置X的值为183,Y的值为46.
用水平stack view布局图片
现在我们继续T-shirt图片.这些图片是水平的,我们用水平的stack views替换.从对象库里拖曳一个水平的stack view到storyboard里.在iOS,我们用image views来显示图片.从对象库里寻找image view对象,把它拖进我们刚添加的stack view.重复这个步骤来添加另外两个image views.如果你添加更多的image views到stack view里,它会自动水平的排列image views.
image view里还没分配任何图片.选择左边的image view然后去Attributes inspector.我们已经添加的T-shirt图片到工程里,image选项自动从asset目录读取图片.点击image选项的下拉菜单选择"t-shirt-1".重复同样的步骤添加其他的image views.你的界面应该看起来像这样:
确保你stack view的位置在X=20 Y=142.选择stack view并且改变它的描述,从Fill变到Fill Equally.设置间隔为10.这会增加在image views之前增加一些空格.
Quick note:看起来stack view已经平分了image view.为什么我们要把属性改变成Fill Equally?记得你现在是在一块自由的画布上设计UI.如果你不明确的把属性设置成Fill Equally,iOS将用Fill分布方案布局image views.它可能在其它设备的屏幕上看起来不那么好
UI现在看起来不错,对吗?如果你运行app或者在界面编辑器里预览UI,它看起来不像预料的那样.因为我们还没给stack views定义布局约束.你仍然需要为stack views创造布局约束.
为stack views添加布局约束
我们将定义下面的界面约束给stack view的标题:
在它和top layout guide之间设置一个隔断约束.
把它水平居中.
从stack view里按住control拖曳到container view.按住shift键,选择"Vertical Spacing to Top Layout Guide"和""Center Horizontally in Container".点击Return来添加约束.
当stack view包含image view时,我们将定义以下的布局约束:
在它和其它stack view之间设置一个边距约束,因此他们之间有个边距.
在stack view左边和视图的左边界之间设置一个边距约束,在他们之间没有空间(即0点).
在stack view右边和视图的右边界之间设置一个边距约束,在他们之间没有空间(即0点).
现在在布局按钮里点击Pin按钮.设置顶部,左边和右边的边距约束分别为15.5,0和0
在模拟器中运行app,布局比之前的版本要更好看了.但是所有的图片显示都拉伸了.
事实上,stack view的高度被修复了,同时宽度发生了变化.因为实际的iPhone屏幕宽度比画布的宽度要小,这是为什么图片显得被拉长了.
为了修复这个问题,我们应该定义更多的约束然后告诉stack view保持纵横比,不用管屏幕的尺寸.在文档概要视图里,按住control拖曳stack view(包含image views).在快捷菜单里,选择"Aspect Ratio".
再次运行project.布局应该看起来很不错.
用stack view布局按钮
让我们继续布局屏幕底部的两个按钮.在这段课程的最开始,我提到过有两个方法来使用stack views.前面,你们从对象库里添加了一个stack view.现在我将展示另一种方法.
首先,从对象库里拖曳一个按钮到视图.双击按钮把它命名为"Sign in".在Attributes inspector里,把它的背景色改成红色,文本颜色改成白色.在Size inspector里,设置宽度(width)为200.
下一步,把另一个按钮拖到视图并且把它命名为"Sign up with email".在Attributes inspector里,把它的背景色改成红色,文本颜色改成白色.在Size inspector里,设置宽度(width)为200.设置好以后,会显示红色的实线.
再说一次,你不需要为这些标签设置布局约束.让stack view为你变个魔法.按住command键来选择两个按钮,然后点击layout栏里的Stack按钮.界面编辑器会自动嵌入他们到一个垂直stack view里.选择stack view给两个按钮增加一个间隔.在Attributes inspector之下,设置间隔值为10.试着让stack view垂直和水平居中.
同理,我们给这个stack view定义布局约束来让它的位置靠近视图的底部.这些是我们准备定义的布局约束:
让stack view水平居中,
设置一个间隔约束来让stack view和Bottom Layout Guide之间有个间隔.
你可以跟随下面的图例来增加约束.
有一件事你可能注意到,按钮比我们希望的要小.当你嵌入按钮到stack view时,他们被重新调整大小.如果你像设置宽度为200,你需要添加一个宽度约束到stack view.在文档视图里,按住control然后拖曳stack view到它自己然后选择宽度来增加约束.
为了改变宽度为200点,在文档概览视图里选择宽度约束.然后到Size inspector,将constant改成200.stack view现在宽度修复成200点.
再测试一下app.在iPhone(或者ipad)上运行这个工程.你的UI应该看起来像下面这样
用Size Classes调整stack views
如果你换个方式运行iPhone模拟器,UI在风景模式下看起来是这样:
它工作得很好.我们来让它看起来更好.我想要改变Top Layout Guide和标题的间隔,同样的,标题和图片的间隔也要改变.但是请注意这些改变仅仅只用提供给风景模式(横屏)下的iPhone.
像你知道的那样,我们可以通过改变间隔约束的量来调整间隔.真正的问题在于:我怎样才能只调整iPhone的风景模式(横屏)?
这里带来一个新的设计概念叫做自适应布局(Adaptive Layout),这是iOS8发布的时候引进的.用自适应布局,你的apps能够让他们的UI来适应一个特殊的设备和设备方向.为了实现自适应布局,苹果介绍了一个新的概念,叫做Size Classes.这可能是实现自适应布局最重要的方面.Size classes是一个抽象概念,说明了一个设备是怎样依靠它的屏幕尺寸和方向来分类的.
一个size class为纵向(高)和横向(宽)尺寸标识了一个显示空间的相对数量.size classes有两种类型:regular和compact.一个regular size class代表了大部分屏幕空间,同时compact size class代表了小部分屏幕空间.通过使用一个size class来描述每个显示尺寸,这将会出现4种结果:Regular width-Regular Height,Regular width-Compact Height,Compact width-Regular Height,Compact width-Compact Height.
下面的表格显示了iOS设备和他们正确的size classes:
为了表现一个显示环境,你需要指定一个横向的size class和一个纵向的size class.比如,iPad有固定的横向size class和固定的纵向size class.在我们的例子里,我们要给iPhone提供特殊的风景模式布局.换句话说,这里我们要处理两个size classes:
Compact width-Compact Height
Regular width-Compact Height
现在回到Main.storyboard.选择Top Layout Guide和stack view的间距约束.在Size inspector里,点击Constant选项边上的+按钮.选择Any Width>Compact heigt,然后设置尺寸值为0.
Quick note: 这里,任何width包括compact和regular width
做完那些之后,当你的iPhone横过来的时候,stack view和Top Layout Guide之间的间距将减到最小.在不同的iOS设备上运行这个工程然后看看结果.
你可以做同样的步骤来调整标题和图片的间距.我把这个留下来给你当练习.
你的练习
为了帮助你更好的理解size classes是怎样工作的,我们来做另外一个简单的例子.要求你创建专门为iPad设备创建另外一个布局.请在iPad上放置水平的按钮来代替横向的stack view来布局Sign in/Sign up按钮.