这两天把XCode升级到了4.5,新建的项目里面控件对齐的时候,找不到Spring and Structs 视图了,如下图所示,很是奇怪。
正常情况下应该是这样的
顺 便网上查询了一下,刚刚开始无从下手,不久发现XCode,其实是iOS 6.0 新增了一个新的功能 叫做 “自动布局" 英文为“Constraints” ,可以在帮助信息中查询 “Auto Layout: Understanding Constraints” 这部分信息。
究竟是什么东东呢? 下面剽窃部分内容来看看
原文 http://www.entlib.net/?p=2591
剩下的根据下面的链接应该都可以找到,下面黏贴下来,目的是避免链接失效
iOS 6编程(14)-自动布局(Auto Layout)简介
iOS 6 在应用程序用户界面开发中,引入了自动布局(Auto Layout)概念。自动布局使用约束(Constraint)在用户界面描述各类视图的位置、行为和关系。
在Xcode 4.5中,我们可以使用Interface Builder,或者可视化格式语言(Visual Format Language),或者标准的SDK API调用(NSLayoutConstraint类)等等三种方式来创建约束(Constraint)。
Auto Layout用这些Constraints 来对所有的视图进行一些计算,设置视图的位置和尺寸。不再需要设置视图的frame属性,也就是完全基于针对视图或元素所设置的Constraints来布局界面的视图元素。
使用Xcode 4.5 创建App时,Auto Layout功能在所有nib或Storyboard 文件中,默认是enable(开启的)。具体设置的地方,可以查看之前的文章。(如果该链接失效,看下面的 “iOS/Xcode异常:reason: ‘Could not instantiate class named NSLayoutConstraint’”)
在iOS 6 引入自动布局之前,我们使用springs and struts模式来设计可旋转和调整大小的用户界面。简单归纳和回顾一下,主要有三种方法:
1. 自动旋转和自动调整大小
通过在Size Inspector面板中,设置各类视图的Autosizing属性,无需编写代码,但这种仅适用于UI比较简单的应用。
2. 调整视图框架(frame属性)
每一个UI 元素在屏幕上都由一个矩形区域定义,这个矩形区域就是UI 元素的frame属性。可以使用C语言函数CGRectMake(x,y,width,height) 来重新定义视图的frame属性。
如果UI元素比较多,这个需要跟踪每一个UI元素的大小和位置,代码设计起来比较麻烦。
3. 重新设计不同的视图-横向和纵向视图
在 每一个场景中分别定义横向和纵向2个视图,这个每一个视图都需要定义独立的输出口。虽然2个视图和同一个视图控制ViewController关联,但是 不能共享输出口,在视图控制器中需要交互的UI元素数量会变成 2 倍。当然优点是,不同的视图完全独立开了,避免相互影响。
上述三种方式在开发过程中,都存在一些缺点。iOS 6 引入的自动布局(Auto Layout)正是为了改进这个不足之处。个人觉得也可以适应之后不断增多的不同尺寸的iPad、iPhone设备。
iOS/Xcode异常:reason: ‘Could not instantiate class named NSLayoutConstraint’
异常信息:Terminating app due to uncaught exception ‘NSInvalidUnarchiveOperationException’, reason: ‘Could not instantiate class named NSLayoutConstraint‘
具体场景:Xcode 4.5 选择iPhone、iPad 5.0/5.1 Simulator(模拟器)
解决办法:需要关闭storyboard或xib界面文件的Use Auto Layout 选项,这是因为Auto Layout特性是iOS 6 新增加的,在之前的 5.0/5.1 Simulator模拟器中不支持。
iOS 6编程(15)-创建自动布局(Auto Layout)简单应用
创建自动布局(Auto Layout)简单应用
在 深入研究Interface Builder的自动布局特性之前,我们先创建一个简单的App,演示自动布局的基本概念。使用Xcode的Single View Application模板创建一个项目,项目名称为AutoLayout,类前缀也设置为AutoLayout,选择Storyboard和 Automatic Reference Counting选项。
在Interface Builder中启动和禁用自动布局功能
默 认情况下,针对Storyboard和单独的NIB文件都会启用自动布局特性。我们从项目导航栏选择MainStoryboard.storyboard 文件,接着显示File Inspector面板,在该监视器面板中,找到Use Autolayout 复选框,如下图所示:
在File Inspector面板中,关闭Use Autolayout选项,我们首先演示没有使用Autolayout特性的情况。
在Autolayout关闭之后,我们拖拉一个按钮到场景视图中,放置在视图的底部水平中心位置,垂直蓝色引导线会出现,表示按钮将放置在水平中心位置。实际上,按钮视图的位置是使用屏幕上硬编码的x和y坐标来定义位置的。只要设备保持纵向模式,按钮位置将非常准确完好。
然 而,在设备转向横向模式时,就出现问题了。可以编译和运行App,然后转向设备。或者在Interface Builder 环境,使用simulated metrics功能来测试转向效果。在文档大纲面板,选择视图控制器(Auto Layout View Controller),然后打开Attributes Inspector面板。在Simulated Metrics栏目,选择Orientation选项,设置为Landscape纵向模式,如下图所示。
另外,针对不同屏幕大小的用户界面布局测试,也可使用上面面板的Size 属性。例如,在4寸iPhone 5屏幕的测试,可设置Size属性为Retina 4 Full Screen。
这个是快速且有效检查布局是否如预期工作的方法。从上图中可以看出,按钮找不到了。这是因为按钮仍然保持着在父视图中相同的位置坐标,在横向模式下,这个位置超出了父视图可视范围。
在之前的iOS 开发中,我们可使用springs and struts,或者编写代码检测设备的转向,将按钮移动到屏幕的新位置。但是,在iOS 6 中,这个问题可以使用自动布局来解决。
现 在,我们将设计界面重新切换会纵向模式,这样按钮会重新显示出来。选择Storyboard文件,在File Inspector面板中,启用Use Autolayout选项。选择按钮,移开当前位置,然后重新移回来,让Interface Builder知道为按钮视图创建约束。默认情况下,Interface Builder将创建约束提供预期的布局行为。当然,这些约束可以查看和修改,但是在本范例程序中,默认创建的约束足够实现自动布局的演示需要的。
再次切换视图到横向模式,这次按钮可以正常显示出来了。
显然,Interface Builder 预想到了用户界面的布局要求。然而,这并不总是符合预期的。针对这一情况,Interface Builder提供了大量的选项和可视化提示,有助于创建自动布局的约束。
iOS 6编程(16)-Interface Builder自动布局功能
Interface Builder自动布局功能
为了帮助基于约束来实现自动布局,Interface Builder增加了大量的功能,下面将阐述这些新功能。
自动化约束
从 前一个范例中,我们知道在视图布局设计过程中,Interface Builder自动给子视图设置了约束。另外,需要知道Interface Builder自动添加的约束和开发人员手工添加的约束是有区别的。手动添加的约束认为是用户约束(user constraints)。Interface Builder 自动添加的约束首先需要调整为user constraints,然后才能删除。user constaints也可以配置为标准间距(standard spacing)。这些在后面的教程中会具体演示。
子 视图在布局上的定位操作,也是指示Interface Builder 配置相应的约束。如在父视图中移动按钮视图到水平中心位置,将出现中心指示线,将按钮放置在此处,将自动创建一个水平中心的约束(center constraint)。移动按钮视图到父视图的边缘位置,将出现边界指示线(margin guideline),如下图所示。如果放置在此处,Interface Builder 将创建一个约束,使用Apple建议的标准间隔距离(standard spacing distance)来固定按钮视图底部和父视图底部之间的间隔。
如果一个视图移动接近另外一个视图的边缘时,垂直指示线也会出现,相同标准设置的约束也会创建。下图是Save按钮接近Cancel按钮时,垂直指示线出现在Save按钮的右侧边缘。
可视化提示
Interface Builder在布局画布中包含了一些可视化提示,突出显示当前视图上配置的约束。当在Interface Builder布局画布中选择一个视图时,该视图相关的约束将可视化显示。例如,在AutoLayout范例程序中,当我们选择画布中的按钮时,一些额外 的线条会显示,如下所示:
穿过按钮中心位置的垂直线条表示设置了按钮视图在父视图水平中心位置的约束(类似于NSLayoutAttributeCenterX 属性)。如果用一个等式描述,可以理解为:
label.NSLayoutAttributeCenterX = superview.NSLayoutAttributeCenterX
按钮下面的I线条,从按钮视图的底部到父视图的底部,表示在2个视图之间设置了一个垂直间隔约束,线条上没有额外的可视化信息,表示这是一个等式约束(equality constraint)。下图显示2个按钮视图之间设置了一个大于等于的水平间距约束:
在 按钮视图中的文本下面的水平线表示设置了2个按钮之间水平对齐文本基线(content baseline)的约束(可用NSLayoutAttributeBaseline表示)。另外,我们注意到水平间距约束线条比水平对齐线条要更粗一 些,比较粗的线条表示这是一个用户约束(user constraint),比较细的线条表示是Interface Builder 自动添加的约束。
宽度约束显示为和视图平行放置的I线条。如下图文本视图对象,设置了大于等于的宽度约束。
查看和编辑约束
所有对视图设置的约束都显示在文档大纲面板中。当视图层次中有多个视图容器时,每一个视图容器(container view)都将有一个单独的约束列表。例如,下图显示了包含2个按钮的用户界面的约束列表:
当在列表中选择任何一个约束时,相应地在布局画布中将显示对应的可视化提示。
可以使用多种方法来显示和编辑特定的约束,其中一种方法是从布局画布(layout canvas)或者文档大纲面板中一个约束,然后在Attributes Inspector面板查看和编辑约束的属性。下图显示了等式间距约束的设置。
在上图中,我们可以修改Relation、Constant、Direction和Priority等等约束的属性值。可以选择Standard复选框,就可以设置间距为Apple推荐的标准间距。
通 过在布局画布选择一个特定视图,在Size Inspector面板中将显示该视图相关的约束列表。如下图所示,列出了当前选择视图的4个相关的约束。点击人一个约束的设置图标,将显示编辑或者删除 约束的选项。如果约束类型不是用户约束(user constraint),则需要首先选择Promote to User Constraint 选项,然后Delete 选项才可以使用。
除 了这些约束外,还有Content Hugging Priority和Content Compression Resistance Priority 属性值也显示在这里。以一个按钮视图为例,可以水平扩展(水平hugging为低优先级),但是不能垂直增长(设置vertical hugging为高优先级)。相似地,按钮文本内容不应该压缩或者省略一部分,因此Content Compression Resistance Priority 的水平和垂直参数都应该设置为比较高优先级。一般而言,我们不必经常调整Interface Builder添加的这些默认设置。
在Interface Builder中创建新的约束
在Interface Builder中有多种方法创建新的用户约束(user constraints),需要记住,约束可以一次关联多个视图。
针对单一视图添加约束(如宽度约束)的一种方法是,在布局画布中选择该视图,然后选择Xcode的Editor > Pin 菜单。Pin 菜单提供了当前选择视图的可用约束列表,如宽度、高度和连接到父视图的所有边界等等。
Editor 菜单也可用来设置多个视图的约束。选择多个视图,然后选择Editor > Pin菜单设置约束。此时设置的约束将应用到所有选择的视图上。
当选择多个视图时,Editor > Align 菜单也可用来对齐选择的视图,如左边界、右边界,baseline等等。
除了使用Editor 菜单之外,还可用快速Interface Builder右下角的迷你工具条,如下图所示:
本节通过一个非常简单的范例,演示了在iOS 6 用户界面设计过程中,使用自动布局所带来的好处。后面,我们还会深入介绍Interface Builder所提供的自动布局的功能。
iOS 6编程(17)-自动布局深入演示
前面我们简单学习了自动布局的一些基础知识和Interface Builder中自动布局的一些功能。这里,我们进行通过一个示例App演示使用Interface Builder创建自动布局的约束,同时也演示了约束的优先级。
进一步在布局画布上,添加了按钮和UIImageView图像视图,通过iOS 6 引入的自动布局和约束,可以方便灵活设计出纵向、横向模式都适应的应用程序。