为iPhone 6设计自适应布局

Apple从iOS 6加入了Auto Layout后开始就比较委婉的开始鼓励、建议开发者使用自适应布局,可是到目前为止,我感受大多数开发者一直在回避这个问题,无论是否是因为历史缘由形成的,至少他们在心底还坚守着固定布局的老传统思想。git

随着iPhone六、iPhone6 Plus的到来,使用自适应布局更是迫在眉睫的事,固定布局的老传统思想脆弱的不堪一击。如今的iPhone有4种尺寸,若是算上iPad,如今Apple的iOS设备有5种尺寸。咱们在准备使用自适应布局设计应用界面以前,能够把这5种尺寸划分为3种分辨率和屏幕方向,这样在设计时分类会更加清晰一些。iphone

咱们先来看一张自适应布局的效果图:编辑器

当大家学习完这篇文章后,大家应该会比较自如的使用 storyboard、constaints、size classes 这三个Apple在Xcode里提供的工具,去探索和构建巧妙的自适应布局。ide

Storyboards工具

在Xcode中,storyboard是一个可让咱们对应用界面进行可视化布局的工具,你首先能够在storyboard文件中看到一个或若干个iOS设备屏幕大小的布局区,而后你能够从组件库(Object Library)中拖拽组件到屏幕布局区中进行布局(好比按钮、图片、文本框、labels等),你还能够定义屏幕布局区之间的链接关系。布局

用Xcode的术语来讲,人们能够看到、触碰到或以其余方式(按钮、图片、文本框、labels等)进行交互的用户界面被称为views。屏幕中包含和管理这些views的容器称为view controller。性能

当咱们在storyboard中添加一个view controller后,咱们所看到的并非一个咱们熟知的屏幕尺寸,而是一个600X600的正方形:学习

从上图咱们能够很明显的看出,storyboard中显示的屏幕尺寸不是实际设备的尺寸。Apple这样作的目的是将屏幕尺寸进行了抽象化,也就是说你能够将这个正方形的屏幕当作iphone4的屏幕,也能够将它当作iphone6的屏幕。动画

模拟器的尺寸ui

当你习惯了600X600的屏幕后,你可能会用着很爽,可是有些时候,咱们也须要将它改为实际的屏幕尺寸来设计一些东西。

咱们能够很方便的在Xcode中改变view controller的模拟屏幕尺寸和屏幕方向:

布局约束

介绍布局约束的最好、最直观的方法就是向大家展现一个示例。

首先咱们将storyboard中的屏幕布局区域的尺寸调整为iphone5s的尺寸,也就是4寸屏幕,而后添加两个正方形的view,并排放置在屏幕顶部,一个设置为蓝色,一个设置为粉色。

咱们选择iPhone5s模拟器设备并编译运行应用,能够看到一蓝一粉这两个方块按照咱们设定的那样杵在竖屏方向的屏幕上,没有问题。当咱们把设备调整为横屏时,这两个方块像拥护党同样拥护着他们的坐标位置,因此在横屏的时候看着就不是那么完美:

咱们再将模拟器改成iPhone6,而后编译运行,此时在竖屏的时候就已经感受没法再爱了。这两个方块并无按照咱们设置或设想的那样在屏幕顶部中间,而是偏向了左边,在右边有一块留白区域。

这是就是没有布局约束而致使的,蓝色粉色方块的大小、坐标位置都是固定的,都是在4寸屏幕的参照下设置的,不论在哪一种尺寸的屏幕下,它们都在固定的那个坐标位置和固定的大小,因此就会出现上面的状况。

那么接下来让咱们给这两个方块添加一些布局约束,再看看会有什么神奇的事情发生。

页边间距约束(Leading and Trailing space)

页边间距约束分前部间距约束(Leading space constaint)和尾部间距约束(Trailing space constaint)。从屏幕上说就是左边距和右边距。咱们给蓝色方块添加左边距约束,其值设置为10,给粉色方块设置右边距约束,其值也设置为10。

咱们再次在iPhone5s模拟器中运行应用,当横屏时蓝色方块被左边距约束拉到了屏幕左边,粉色方块被右边距约束拉到了屏幕右边。

水平间距约束(Horizontal space constaint)

给蓝色方块和粉色方块添加水平间距约束,其值设置为10。这个约束会使这两个方块之间的距离永远约束为10。

咱们再来运行应用,如今横屏时两个方块之间的间距、它们与屏幕边缘的间距都和竖屏时显示的同样了。可是其中粉色方块为了知足水平间距约束自行增长了方块的宽度,变成了长方形。简直是一只老鼠坏了一锅汤有木有。

从上面这个效果咱们能够得知,除非咱们特别限制了view的尺寸,不然的话iOS会为知足布局约束而改变view的尺寸,也就是保持一个天然的尺寸。

等宽约束(Equal widths constaint)

咱们给这两个方块添加一个等宽约束来改善上面的状况。

再次运行应用,如今在横屏时因为等宽约束的做用,两个方块的宽度保持了一致。咱们已经很是接近完美了。

方向比例约束(Aspect ratio constaint)

从上面的运行状况来看各个约束都工做正常,但惟一不足的是原本在竖屏是两个正方形方块,在横屏时缺变成了长方形方块,由范爷变成了凤姐这是人类没法接受的。

咱们给这两个方块添加方向比例约束来解决这个问题。这个约束使方块在知足其余约束的前提下始终保持高和宽的比例相同。因此在横屏时就会以方块的宽度为比例标准,将高度的比例改成宽度的比例。

用iPhone5s模拟器编译运行应用,如今在横屏状态下两个正方形方块完美的呈如今咱们眼前。

咱们在iPhone6模拟器上再编译运行应用,从下面的图中咱们能够很清晰的看到添加约束以前和以后的变化。布局约束根据多出的空间大小将方块放大到合适的尺寸以知足约束。

实践布局约束

到目前为止,大家已经看到布局约束神奇的做用和效果。是时候让大家在大家本身的storyboard文件中添加布局约束了。

熟练布局约束最好的方法就是多练习,从添加少许的布局约束开始,一步步达到本身想要的效果。

另外有一点,我始终不认为添加过多的布局约束会对应用的性能产生影响。可是咱们也不能滥用约束布局,好钢要用在刀刃上,咱们尽量用最节俭的约束布局达到咱们想要的效果。

添加布局约束的方式

这里向你们介绍三种在storyboard中添加约束的方式:

1.底部布局约束按钮

这种方式多是最简单直观的一种方式,在屏幕上选择一个或多个对象,而后点击底部的布局约束按钮添加一个或多个须要的约束。它的好处是能够直观的看到当前选择的对象已经添加了该类中的那些约束。

若是你指选择了一个对象想要添加某个约束,但发现该约束是不可选的,那么就意味着这个约束是适用于两个以上对象的约束。

2.按住Control键拖拽鼠标

你也能够选择一个对象,而后按住Control键和鼠标左键,拖拽鼠标到另外一个对象(容器对象,也就是父对象或者选中对象本身),松开鼠标后会弹出适用的约束菜单,你能够选择约束进行添加。

这是我偏心的一种方式,由于它比上面那种方式来的快多了。

 

3.菜单/绑定快捷键

你也能够经过菜单选项editor —> pin给一个或多个对象添加布局约束。这是效率最低的一种方式。若是你发现有些约束你会一遍遍的反复添加,那么你就能够给该约束绑定一个快捷键来提升效率。

检查和编辑已添加的布局约束

检查约束最简单的方式就是选中一个对象,而后打开右侧工具栏,选择Size Inspector面板。或者在storyboard界面左侧的结构树中查看约束。

经过这两种方式,你均可以选择某个约束,而后编辑它。

移除布局约束

布局约束能够添加天然也就能够删除。选中某个约束使其高亮显示,而后按下Delete键移除该约束。

若是想移除某个对象上全部的约束,有一个快捷的方式。选择该对象,而后在底部点击Resolve Auto Layout Issues按钮,选择Clear Constaints。

布局出现的问题和冲突

咱们在添加约束时,常常伴随有警告或者错误出现。虽然有些警告是由于咱们尚未添加完约束出现的,当咱们添加完咱们设想的约束后警告就会天然消失。但大多数的警告仍是指明咱们的约束确实存在问题,须要咱们修复。

查看警告或错误最方便的方式就是在storyboard左侧的结构树中,在view controller的右边会出现一个红色或黄色的小图标,向咱们指明这里存在问题:

错误摆放view的警告

view位置的错误摆放是一个很常见的警告。当一个view没有摆放在约束规定的位置的时候,会出现该警告。

这些问题会在你切换不一样设备的模拟器或鼠标不当心移动了某个对象时出现。

选中一个错误摆放的对象,在屏幕上会出现布局约束给你提示的正确的摆放位置。

点击左侧出现的黄色警告图片,会弹出一个菜单,你能够选择让Xcode改变约束,以适应当前该对象的位置,但一般状况下咱们都选择让Xcode将该对象移动到约束规定的位置。

缺乏布局约束的错误

咱们回到早些时候的示例中。这时候咱们没有给方块添加Y坐标位置的约束。在运行时没有问题,由于iOS会假设方块的位置就是咱们在storyboard中摆放的那个位置。可是Xcode会提示咱们一个缺失约束的错误,为了不意外发生(更换设备尺寸),我仍是要根据Xcode的提示添加缺失的约束。

咱们给这两个方块添加一个top space to to layout guide约束使方块的位置更加清晰,并消除Xcode的错误提示。

 Size Classes

自适应布局的布局约束天然是好东西,但也不是万能的,有时候咱们也须要使用最基本的布局,因此使用size classes将它们二者结合起来才能碰撞出更有激情的火花。

Size Classes并不表明真正的尺寸,而是咱们从感官上感受尺寸的种类,经过这种种类的组合,表示出不一样屏幕尺寸设备的横屏及竖屏。

咱们在给storyboard中的对象添加约束时能够选择给某一个size class添加约束,因此在你选择特定的size class时,只能看到你添加的只适用于该size class的约束。

这些特性能使咱们有效的在不一样的设备和屏幕方向中定义、设计不一样的用户界面。

Size Classes中的高和宽

Size Classes为高和宽分别提供了三种类型:紧凑型(compact)、普通型(regular)、任意型(any)。用这三种高和宽的类型就能够组合出9种size class,来表示不一样的设备屏幕。

在实际运用中,咱们发现并非全部的尺寸都能在Size Classes中找到明确的组合(好比没有组合能够明确表示iPhone6 Plus的竖屏,iPad的横竖屏也很差区分),可是咱们可使用表示这个尺寸范围的组合。好比咱们能够用Compact Width | Regular Height来表示iPhone6 Plus的竖屏。

接下来仍是用一个活生生的示例来向你们介绍Size Classes。

咱们的目标

这个示例是实现Instagram的一个详细信息页面,并让它自适应更大的屏幕尺寸,在竖屏和横屏中都展示出最合适的布局。

咱们的目标是让布局自适应iPhone6的屏幕(这里须要注意一下,我所说的自适应是指图片、文字信息的布局排版,对于我的信息的头像不会根据布局的变化而变化),在竖屏中各个信息按照堆栈方式从上到下布局,在横屏时各元素按照大小进行有序排列,而再也不是堆栈的方式:

给通用的size class添加约束

在这个示例中,咱们不会像上个示例那样使用模拟器的实际尺寸来设计布局,咱们使用Size Classes提供的抽象的屏幕尺寸,这里咱们先使用通用的尺寸来设计布局,也就是w Any | h Any尺寸。咱们要注意的是,在这个尺寸下添加的view或者约束必须是一些公用的,也就是说在任何尺寸,任何屏幕方向的状况下都适用的。

这些约束包括:

除了以前介绍过的页边间距约束、水平间距约束、等高等宽约束、方向比例约束外还有顶部、底部间距约束。

添加完上述的view和约束后,storyboard里应该是这番景象:

这里要注意一下,目前这个界面的布局还有不少关键点须要考虑横屏和竖屏的布局,可是这些工做不会在w Any | h Any尺寸下进行。大伙接着往下看。

为iPhone的竖屏添加布局约束

如今在Size Classes选择器中选择w Compact | h Regular尺寸,这个size class适用于全部iPhone设备的竖屏界面,不论尺寸是多少。

当你在Size Classes选择器中选择某一个size class后,storyboard 中的view controller会实时的反映出你改变后的尺寸大小。

如今你就能够为iPhone的竖屏状态从新设计view的位置和添加新的布局约束了。下图中说明了我在竖屏状态下添加的约束:

个人storyboard中看起来是这样的:

在这个阶段,你能够在3.五、四、4.七、5.5这几个尺寸的模拟器中编译运行应用,在竖屏状态下看看它们的运行状况,尽管在横屏状态表现的还很糟糕。

这里要注意的是咱们并无定义图片的宽度,咱们只是给图片添加了相对父容器的左右边间距,并将其值设为了0。因此当屏幕尺寸增大的时候图片的宽度在布局约束的做用下也会增长,这时又由于咱们给图片添加了高宽比例约束,因此图片的高度也会随之增长。

为iPhone的横屏添加布局约束

打开Size Classes选择器,选择w Any | h Compact,这个size class适用于任何一个尺寸的横屏状态。咱们将在这个size class下设计咱们但愿在iPhone横屏时显示的用户界面。

此时图片的顶部、左侧、底部都添加了相对于父容器的边界约束。在显示评论的label上添加了右侧边界约束。

当设备横屏时,图片在布局约束的做用下移到了左侧,我的信息label和评论label在约束的做用下被挤到了右侧,而且评论label的高度增长,宽度减小。

如今来看看个人storyboard中显示的内容。你们注意左侧的对象结构树中有不少个约束,可是有些是灰色的。那是由于这些灰色的约束在当前的size class下是禁用的,或者说不适用、不起做用。那些是竖屏时用到的约束。

如今在storyboard中切换size class时布局也会随之变化,更新很是及时和平滑。

咱们在模拟器中编译运行应用,切换横竖屏,能够看到布局切换的效果,过分很是天然平滑。

为了能让你们看清楚布局变化过分的细节,我放慢了这个git动画。你们注意,在布局变化时屏幕上的组件有一个层级关系,从该示例中咱们能够看到图片view的层级高于我的信息label和评论label。因此咱们在设计布局的时候就要考虑如何给view分层,包括在普通布局中不会被覆盖的view。这是一个细节问题。

屏幕预览助手编辑器

Xcode6中另外一个值得关注的功能是屏幕预览助手。它能够避免你一遍遍的在不一样屏幕尺寸的模拟器中编译运行应用来检查布局的正确与否。你能够在屏幕预览编辑器中添加一个或多个你想查看的屏幕尺寸,并可让他们呈现横屏或竖屏的状态。

固然它也不是很是完美(由于在预览时导航栏的颜色会丢失),可是切换Double Length Pseudolanguage选项很方便,便于你检查问题。

从上图中你们能够看到我在屏幕预览编辑器中显示了3.5寸屏幕的横屏和4寸屏幕的竖屏,总体布局没有问题,可是当选择Double Length Pseudolanguage使label中的文字都增长一倍时,问题就出现了,我的信息和评论的label长度没有自适应。

为iPad布局添加约束

如今咱们将Sizae Classes调整为w Regular | h Regular,这个size class表示了iPad的横屏和竖屏大小。

和往常同样,咱们先调整图片和各个label的位置及大小,调整满意后,再添加相关的约束。在iPad布局中我打算将图片的尺寸设置为固定尺寸(不像iPhone中那样随着横屏和竖屏改变图片的尺寸),并将我的信息和评论label紧跟在图片下面。

个人storyboard如今看起来是这样的:

以往,咱们都是在特定的size class中添加相关的约束,但在iPad布局中,咱们不只仅只添加一些约束。

由于在iPad布局中有很大的空余空间,因此咱们不仅是从新排列一下组件的位置和大小,咱们还要添加一些其余的组件。在这个示例中,咱们再添加两个图片view(分别表示当前显示图片的上一张图片和下一张图片)。

再来看看个人storyboard:

咱们不须要对这两个图片手动的设置高宽,而是给它们设置对于主显示图片的相对高宽便可。

这样作的好处是当主显示图片的尺寸更改时,咱们不须要本身手动计算和更改这两个图片的尺寸,相对高宽会自动针对主显示图片的尺寸调整这两个图片的尺寸。

我没有制做在iPad上运行的gif动画,但这里有iPad横屏竖屏的运行图片,你们能够看看:

使用布局视图和间距视图

目前Xcode提供的布局约束能够知足大部分的布局需求,可是有些场景下须要变通的使用约束才能达到咱们想要的效果。

布局视图示例

经过Xcode提供的约束,咱们能够很容易设置组件与view controller view的边缘的间距,也能够很容易的让组件在view controller view中水平居中显示和垂直居中显示。可是却不太容易设置组件与view controller view的水平中线或垂直中线的间距。像这样:

下面向你们介绍两种实现该需求的方法。首先咱们先添加一个view,背景色设置为透明,让它在屏幕中垂直居中显示,它做为该需求中组件的父容器,由于父容器在屏幕中是垂直居中的,因此能够给组件添加相对于父容器的Center X约束,就能够达到咱们的需求了:

可是经过上述的方式未免会使咱们的布局的层级关系太过复杂,我更但愿布局比较扁平一些,不须要太多的层级关系。由于上述方法中的容器view主要是用于布局使用,因此这种view我称之为布局视图。

咱们来改进一下方法,首先也是在view controller view中添加一个布局视图,我习惯将高度设置为20(这个值随我的喜爱或实际状况而定),而后将它和屏幕的顶部、左侧、右侧的间距设为0,这样的话这个布局视图就和状态栏重合了,咱们将这个布局视图设置一个深一点的颜色,而后将它的hidden属性设置为true,这样布局视图的颜色就会变浅,也不太会影响咱们的布局,并且在应用运行时是不会显示该视图的。如今咱们的组件就能够设置相对于布局视图的Center X约束来实现咱们的需求了。

间隔视图示例

以前咱们学习了如何使用约束设置视图和视图边缘的间距,而且当屏幕尺寸增长时视图也会相应的改变大小,但它们的间距不会改变。

可是若是咱们但愿当屏幕增长尺寸时,视图的大小保持不变,只是增长间距呢?

从理论上讲,实现该需求可能可使用相似等宽这样的约束,可是现实每每的是骨干感的。

这时咱们就须要间距视图出场了,和布局视图同样,间距视图能够设置一个深一点的颜色,hidden属性要设置为true。

咱们在每一个视图与视图间距之间添加一个间距视图,设置每一个视图与相邻间距视图的边缘间距约束,而后给全部的间距视图添加相对于view controller view的等宽约束,设置合适的比例便可。

相关文章
相关标签/搜索