Gallery example

屏幕有四个分开的相同的矩形,每个矩形有一个label和一个image view。创建一个Gallery的项目。在Main.storyboard中,拖拉一个view大小为160 by 284 points。

Note: There are two main reasons why you would drop a plain UIView onto a storyboard:

a) You’re going to use it as a container for other views, which helps with organizing the content of your scenes; or

b) It is a placeholder for a custom view or control, and you will also set its Class attribute to the name of your own UIView or UIControl subclass.

现在设置一些约束。你已经知道了两种约束,使用Editor\Pin和Align菜单。或者ctrl+dragging控件来实现。然后还有一种方式是使用下面的工具选项。

Align, Pin, Resolve Auto Layout Issues, and Resizing Behavior从左到右依次是对齐,固定,解决auto layout问题,重定义大小。

前三个选项顶部的菜单栏目中都一样的,resizing behavior允许你当resize view的时候改变约束

选择pin弹出如上的筐体。然后点击四个T-bar颜色会变成solid red,最后选择add 4 constrains选项就会产生新的约束。

选择Assistant editor中的priview也可以先预览模拟器竖屏和横屏的效果图

Note: Maybe you wondered why the constraint at the top of the view didn’t go all the way up to the top of the screen:

Instead it stops at the status bar. But in iOS 7 the status bar is always drawn on top of the view controller — it is no longer a separate bar — so what gives? When you created the constraint it didn’t actually attach to the top of the screen but to an invisible line called the Top Layout Guide.

On a regular view controller this guide sits at 20 points from the top of the screen, at least when the status bar is not hidden. In a navigation controller it sits below the navigation bar. Because the navigation bar has a different height in landscape, the Top Layout Guide moves with the bar when the device is rotated. That makes it easy to place views relative to the navigation bar. There is also a Bottom Layout Guide that is used for the tab bar and toolbars.

为了不让模拟器旋转后宽度和高度发生变化,那么你可以设置宽度和高度

运行app,报错误

2015-01-04 10:25:58.691 Gallery[888:279956] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
    "<NSLayoutConstraint:0x7f8adae04f50 H:[UIView:0x7f8adac0b950(160)]>",
    "<NSLayoutConstraint:0x7f8adae08360 UIView:0x7f8adac0b950.leading == UIView:0x7f8adae05d80.leadingMargin + 204>",
    "<NSLayoutConstraint:0x7f8adae083b0 UIView:0x7f8adae05d80.trailingMargin == UIView:0x7f8adac0b950.trailing + 204>",
    "<NSLayoutConstraint:0x7f8adeb6c870 'UIView-Encapsulated-Layout-Width' H:[UIView:0x7f8adae05d80(375)]>"
)

Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7f8adae04f50 H:[UIView:0x7f8adac0b950(160)]>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2015-01-04 10:25:58.693 Gallery[888:279956] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
    "<NSLayoutConstraint:0x7f8adae08360 UIView:0x7f8adac0b950.leading == UIView:0x7f8adae05d80.leadingMargin + 204>",
    "<NSLayoutConstraint:0x7f8adae083b0 UIView:0x7f8adae05d80.trailingMargin == UIView:0x7f8adac0b950.trailing + 204>",
    "<NSLayoutConstraint:0x7f8adeb6c870 'UIView-Encapsulated-Layout-Width' H:[UIView:0x7f8adae05d80(375)]>"
)

Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7f8adae083b0 UIView:0x7f8adae05d80.trailingMargin == UIView:0x7f8adac0b950.trailing + 204>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2015-01-04 10:25:58.693 Gallery[888:279956] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
    "<NSLayoutConstraint:0x7f8adae05be0 V:[UIView:0x7f8adac0b950(284)]>",
    "<NSLayoutConstraint:0x7f8adae08400 V:[_UILayoutGuide:0x7f8adae06db0]-(81)-[UIView:0x7f8adac0b950]>",
    "<NSLayoutConstraint:0x7f8adae08450 V:[UIView:0x7f8adac0b950]-(215)-[_UILayoutGuide:0x7f8adae07ca0]>",
    "<_UILayoutSupportConstraint:0x7f8adae080f0 V:[_UILayoutGuide:0x7f8adae06db0(20)]>",
    "<_UILayoutSupportConstraint:0x7f8adae08290 V:|-(0)-[_UILayoutGuide:0x7f8adae06db0]   (Names: '|':UIView:0x7f8adae05d80 )>",
    "<_UILayoutSupportConstraint:0x7f8adae08ab0 V:[_UILayoutGuide:0x7f8adae07ca0(0)]>",
    "<_UILayoutSupportConstraint:0x7f8adae08150 _UILayoutGuide:0x7f8adae07ca0.bottom == UIView:0x7f8adae05d80.bottom>",
    "<NSLayoutConstraint:0x7f8adeb6c8c0 'UIView-Encapsulated-Layout-Height' V:[UIView:0x7f8adae05d80(667)]>"
)

Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7f8adae05be0 V:[UIView:0x7f8adac0b950(284)]>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

还记得之前说的必须设置足够的约束来使得auto layout知道如何布局?而现在的情况是设置的约束太多了。有冲突的地方。一旦报错 “Unable to simultaneously satisfy constraints”, 就是说明你设置的约束太多了有冲突。让我们来看看怎么回事。

可以看到屏幕中设置了6个约束,四个之前的约束1-4然后还有新的宽度和高度约束可以查看5和6.那么冲突在哪里呢?在竖直的模式下不应该有问题因为数学运算。superview的宽度是320 points。如果你添加水平距离长度和宽度约束,然后你应该最终得到320. 计算原则是98+160+62 = 320 (就是左边筐到view左边框的宽度+view的宽度+view右边筐到superview右边筐的距离)同样的垂直的约束应该是568 。但是当你旋转设备到横屏的状态时,窗口是568 points宽度。意思是98+160+62+?= 568.有248额外的points auto layout无法得知如何获得。
冲突在于:要么view的宽度确定并且其中一个margins必须可变或者margins确定并且width可变。你不能同时将他们的值都设定死。所以其中一个约束需要删除。在上面的例子中,你想让view的宽度和高度在旋转时候都保持不变那么trailing 水平距离就必须要删除掉。删除右侧的horizontal space和底部的vertical space。

再次运行app正常了。

Painting the portraits

添加一个新的Label到view中去,你可以注意到guides出现了,因为它将是label的superview

设置label的约束,水平居中布局

拖拉Image View进去

1. Drag the image view into the green view but don’t worry too much about its size or position:

2. With the image view selected, press the Pin button and choose the following options:

一定要选择Items of New Constraints给update frames选项,不要是默认的,否则auto layout会显示成如下的样子,因为你设定的frame和默认的imageview的frame有冲突所以不对。

当然你也可以用如下的方式来修改成这个效果Resolve Auto Layout Issues

Download the resources for this tutorial 下载图片资源文件,设置Ray.png 把背景设置成白色然后把图片的适应方式设置成Aspect Fit

可以发现在绿色view中的约束变成了橘色。当你设置image view的时候会出现这个问题。那么你的layout怎么会突然失效了呢?幸运的是xcode可以告诉你哪里错了。

有一个content priority ambiguity的错误。意思是:image view和label没有固定的高度。auto layout不知道scale多少如果green view改变高度的话。(interface builder似乎忽略这点green view实际上有一个固定的高度约束)

比如说你的green view高了100 points。那么auto layout如何在label和image view间分配这新的100 points呢?当label 还是之前的大小image view会增高100 points吗?或者当image view还是之前的大小label会增高100 points吗?他们都有额外的50 points还是他会分隔成25/75, 40/60或者其他可能的划分呢?

如果你不解决这个问题那么auto layout就必须猜并且结果可能是出乎预料的。

合适的解决方案是改变label的content compression resistance priority。选择label的size inspector设置vertical content compression resistance priority为751.这样label的priority就会高于image view的。设置content hugging priority为252.这两个数都是报错时候显示的建议数字。imageview的默认的夜市750,251,这样就高于imageview了

警告没有了

Adding the other heads

把green view拖拉到左上角。使用Resolve Auto Layout IssuesUpdate Constraints.delete that “Vertical Space (-20)” constraint

选择⌘D来复制一个同样的并且移动到右上角,出现了橘色,设置top和trailing to right就可以了

同样的复制两个再分别pin到左下和右下方

但是横屏的话却是有问题的

之所以这样是因为你设置了固定的宽度和高度,因此他们总是这样的高度和宽度而不会虽然superview的高度和宽度的变化而变化

选择Width (160) and Height (284)并且删除,再次运行就会是如下的样子:

Note: If you’re wondering why some of the views are larger than others, this is again related to the intrinsic content size. The size of the image determines how large the image view is; the size of the text determines how large the label is. Taken together with the constraints for the margins — 20 points on all sides — this determines the total size of each view.

在document line中使用选择所有的有颜色的view,你可以一次添加所有的约束。在pin中选择equal widths and equal heights并且选择add 6 constraints。再次运行还是不对,但是你会发现所有的view宽度和高度都一样了。

这是因为他们之间没有约束,auto layout不清楚如何布局他们。

选择ray和matthijs并且选择Pin\Horizontal Spacing.因为他们是side by side,这样添加一个他们之间的horizontal space 0的约束并且足以让auto layout知道这两个view是有关联的。并且在ray和dennis之间添加一个Editor\Pin\Vertical Spacing

Run the app again, and this time it looks all right:

Beginning Auto Layout Tutorial in iOS 7: Part 6的更多相关文章

  1. Beginning Auto Layout Tutorial in iOS 7: Part 3

    How Auto Layout works 在使用auto layout之前,你可能总是使用initWithFrame或者frame, bounds or center属性. 使用约束的好处在于你不需 ...

  2. Beginning Auto Layout Tutorial in iOS 7: Part 1

    可以更好的结局屏幕方向和兼容iphone和ipad的解决方案. iOS6有一个新的技术auto layout来帮助解决这个问题.这个技术不仅可以支持app不同尺寸下的开发,而且你也不需要为每一种语言创 ...

  3. Beginning Auto Layout Tutorial in iOS 7: Part 4

    A little runtime excursion 为两个button都添加同一个ibaction方法在viewcontroller.m中实现如下的方法:

  4. Beginning Auto Layout Tutorial in iOS 7: Part 2

    Auto Layout to the rescue! 接下来就看看如何使用Auto Layout来实现这个效果. 首先移除viewWillLayoutSubviews方法,选择Main.storybo ...

  5. Swift语言Auto Layout入门教程:上篇

    原文:Beginning Auto Layout Tutorial in Swift: Part 1/2,译者:@TurtleFromMars 开始用自动布局约束的方式思考吧! 更新记录:该教程由Br ...

  6. iOS布局之Auto Layout

    学习资源: <iOS6核心编程>自动布局部分 <iOS6范例经典>自动布局部分 Tutorial: iOS 6 Auto Layout versus Springs and S ...

  7. How to Use Auto Layout in XCode 6 for iOS 7 and 8 Development

    The Auto Layout is available on the Storyboard for iOS or OS X development since XCode 5. But, I did ...

  8. iOS Programming Auto Layout: Programmatic Constraints 自动布局:通过编程限制

    iOS Programming  Auto Layout: Programmatic Constraints  1.  However, if your views are created in co ...

  9. 【转】使用 Auto Layout 的典型痛点和技巧

    layoutIfNeeded()强制立刻更新布局 原文网址:http://www.jianshu.com/p/0f031606e5f2 官方文档:Auto Layout Guide 加上去年WWDC上 ...

随机推荐

  1. 微信公众开发api接口

      简介 微信公众平台消息接口为开发者提供了一种新的消息处理方式.微信公众平台消息接口为开发者提供与用户进行消息交互的能力.对于成功接入消息接口的微信公众账号,当用户发消息给公众号,微信公众平台服务器 ...

  2. 59、小米电视安装apk(无u盘操作)

    第一步 打开电视或者盒子,找到应用商店 第二步 打开应用商店 第三步.打开应用商店后,找到用户,别切换到快捷安装 第四步.记住地址,使用在同一网络下的电脑打开此网页 第五步.页面效果如图 第六步.找到 ...

  3. LuffyCity-MySQL综合练习50实例

    1.请创建如下表,并添加相应约束: 2.自行构造测试数据: 新建数据库 创建表 构造测试数据 #Step1-创建数据库LuffyCity_MySQL; #CREATE DATABASE LuffyCi ...

  4. Leetcode 525.连续数组

    连续数组 给定一个二进制数组, 找到含有相同数量的 0 和 1 的最长连续子数组. 示例 1: 输入: [0,1] 输出: 2 说明: [0, 1] 是具有相同数量0和1的最长连续子数组. 示例 2: ...

  5. 深入学习之mysql(五)连接查询

    深入学习Mysql(五)连接查询 1.准备数据库: CREATE DATABASE IF NOT EXISTS `db_book2` DEFAULT CHARACTER SET UTF8; USE ` ...

  6. IE IE8 iframe的onload方法分析 IE浏览器onload事件失效

    判断iframe是否加载完成的完美方法 IE 支持 iframe 的 onload 事件,不过是隐形的,需要通过 attachEvent 来注册. 第二种方法比第一种方法更完美(采用readystat ...

  7. hdu 4289 网络流拆点,类似最小割(可做模板)邻接矩阵实现

    Control Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  8. activemq概念介绍

    ActiveMQ概念介绍 是Apache下的开源项目,完全支持JMS1.1和J2EE1.4规范的JMS Provider实现,消息中间件. 消息中间件: A传递消息到B(功能或者系统),有比较强的耦合 ...

  9. eclipse中xml文件报错异常处理

    最近一个Javaweb工程中常出现xml文件的xsd验证失败信息,异常如下: <?xml version="1.0" encoding="UTF-8"?& ...

  10. 在iBatis中操作Blob数据类型

    这里的Blob数据类型指的是保存了文本的blob数据类型 直接读取blob类型存储的文本,可能会出现乱码,所以需要读取完后进行手动转码 这里使用ibatis作为持久层 SELECT urlconten ...