在XCode5中,如果我们添加一个Button或者Label,或者其他的什么标准View,而不设置任何constraints,IB会自动生成constraints,而这些constraints是fixed,无法根据intrinsic content size的变化而变化,这并不是我们想要的。比如,我在View中添加一个label, label的title是Label,另加一个Button,点击Button后改变label的title为很长的文字,并且调用invalidateInstrinsicContentSize,在执行前后,分别打印constraints,代码如下:

    NSLog(@"current constraints %@ ", [[self textLabel] constraintsAffectingLayoutForAxis:UILayoutConstraintAxisHorizontal]);
NSLog(@"current constraints %@ ", [[self textLabel] constraintsAffectingLayoutForAxis:UILayoutConstraintAxisVertical]); [[self textLabel] setText:@"weuituwjaskdtuqwieotuasdjgakleutaiosgajksdgequwtioasdjgkasjdgkajskgd"];
[[self textLabel] invalidateIntrinsicContentSize];
NSLog(@"current constraints %@ ", [[self textLabel] constraintsAffectingLayoutForAxis:UILayoutConstraintAxisHorizontal]);
NSLog(@"current constraints %@ ", [[self textLabel] constraintsAffectingLayoutForAxis:UILayoutConstraintAxisVertical]);

这时看到的输出是

2014-07-04 17:46:28.580 AutoLayoutExample[1110:70b] current constraints (
"<NSIBPrototypingLayoutConstraint:0x8b95fb0 'IB auto generated at build time for view with fixed frame' H:|-(179)-[UILabel:0x8b93e80](LTR) (Names: '|':UIView:0x8b95290 )>",
"<NSIBPrototypingLayoutConstraint:0x8b960e0 'IB auto generated at build time for view with fixed frame' H:[UILabel:0x8b93e80(42)]>"
)
2014-07-04 17:46:28.582 AutoLayoutExample[1110:70b] current constraints (
"<NSIBPrototypingLayoutConstraint:0x8b95d60 'IB auto generated at build time for view with fixed frame' V:|-(147)-[UILabel:0x8b93e80] (Names: '|':UIView:0x8b95290 )>",
"<NSIBPrototypingLayoutConstraint:0x8b96110 'IB auto generated at build time for view with fixed frame' V:[UILabel:0x8b93e80(21)]>"
) 2014-07-04 17:46:28.586 AutoLayoutExample[1110:70b] current constraints (
"<NSIBPrototypingLayoutConstraint:0x8b95fb0 'IB auto generated at build time for view with fixed frame' H:|-(179)-[UILabel:0x8b93e80](LTR) (Names: '|':UIView:0x8b95290 )>",
"<NSIBPrototypingLayoutConstraint:0x8b960e0 'IB auto generated at build time for view with fixed frame' H:[UILabel:0x8b93e80(42)]>"
)
2014-07-04 17:46:28.587 AutoLayoutExample[1110:70b] current constraints (
"<NSIBPrototypingLayoutConstraint:0x8b95d60 'IB auto generated at build time for view with fixed frame' V:|-(147)-[UILabel:0x8b93e80] (Names: '|':UIView:0x8b95290 )>",
"<NSIBPrototypingLayoutConstraint:0x8b96110 'IB auto generated at build time for view with fixed frame' V:[UILabel:0x8b93e80(21)]>"
)

可以看出IB产生的是IB auto generated at build time for view with fixed frame,无论intrinsic content size如何变化,都无济于事。所以,在使用AutoLayout时,切记:每个元素都应该有能完全确定size和位置的constraints, 如果有一样不能确定,IB都会提示Error 或者Warning,而这些Error或者Warning也是必须解决的。

关于两种PlaceHolder

placeholder constraits 和placeholder instrinsic content size

placeholder constraits是说这个constraint只是个placeholder,在build时就会被去掉,这样可以阻止IB自动生成constraints;placeholder instrinsic content size是說在IB中设计时使用的size,在runtime时则需要调用intrinsicContentSize方法来确定。

下面说说intrinsicContentSize和constraint的关系:intrinsicContentSize和constraint是Auto Layout的支柱概念,缺一不可。同时有时intrinsicContentSize可以在某个方面也是一种constraint,通常unambiguous layout generally requires setting two attributes in each axis(也就是在一个维度上需要设置起点和长度两个信息). When a view has an intrinsic content size, that size accounts for one of the two attributes.(如果一个view 有intrinsicContentSize,并且设计者想这样,intrinsicContentSize是可以起到那个长度的限制作用的) You can, for example, place a text-based control or an image view in the center of its superview, and its layout will not be ambiguous. The intrinsic content size plus the location combine for a fully specified placement. 能够这样的前提是1. 使用系统的标准View,2. 在IB中指定Intrinsic size时需要用Default(System defined),比如如果只指定位置信息,不指定size,使用system default intrinsic size,时,输出时这样的

2014-07-04 22:25:40.866 AutoLayoutExample[2237:70b] current constraints (
"<NSLayoutConstraint:0x8a6bde0 H:|-(179)-[UILabel:0x8a6a010] (Names: '|':UIView:0x8a6b400 )>",
"<NSContentSizeLayoutConstraint:0x8b847a0 H:[UILabel:0x8a6a010(42)] Hug:251 CompressionResistance:750>"
)
2014-07-04 22:25:40.868 AutoLayoutExample[2237:70b] current constraints (
"<NSLayoutConstraint:0x8a6bd30 V:[_UILayoutGuide:0x8a6b4b0]-(127)-[UILabel:0x8a6a010]>",
"<_UILayoutSupportConstraint:0x8a67660 V:[_UILayoutGuide:0x8a6b4b0(20)]>",
"<_UILayoutSupportConstraint:0x8a6a300 V:|-(0)-[_UILayoutGuide:0x8a6b4b0] (Names: '|':UIView:0x8a6b400 )>",
"<NSContentSizeLayoutConstraint:0x8b847e0 V:[UILabel:0x8a6a010(21)] Hug:251 CompressionResistance:750>"
)
2014-07-04 22:25:40.869 AutoLayoutExample[2237:70b] current constraints (
"<NSLayoutConstraint:0x8a6bde0 H:|-(179)-[UILabel:0x8a6a010] (Names: '|':UIView:0x8a6b400 )>",
"<NSContentSizeLayoutConstraint:0x8b847a0 H:[UILabel:0x8a6a010(42)] Hug:251 CompressionResistance:750>"
)
2014-07-04 22:25:40.870 AutoLayoutExample[2237:70b] current constraints (
"<NSLayoutConstraint:0x8a6bd30 V:[_UILayoutGuide:0x8a6b4b0]-(127)-[UILabel:0x8a6a010]>",
"<_UILayoutSupportConstraint:0x8a67660 V:[_UILayoutGuide:0x8a6b4b0(20)]>",
"<_UILayoutSupportConstraint:0x8a6a300 V:|-(0)-[_UILayoutGuide:0x8a6b4b0] (Names: '|':UIView:0x8a6b400 )>",
"<NSContentSizeLayoutConstraint:0x8b847e0 V:[UILabel:0x8a6a010(21)] Hug:251 CompressionResistance:750>"
)

如果只指定位置信息,但不指定size信息,但intrisic size是PlaceHolder,width 和height 都是None时输出是这样的:

2014-07-04 21:11:56.941 AutoLayoutExample[1790:70b] current constraints (
"<NSLayoutConstraint:0x8ad9670 H:|-(179)-[UILabel:0x8ad7880] (Names: '|':UIView:0x8ad8c90 )>",
"<NSIBPrototypingLayoutConstraint:0x8ad9c10 'IB auto generated at build time for view with ambiguity' H:[UILabel:0x8ad7880(42@251)] priority:251>"
)
2014-07-04 21:11:56.942 AutoLayoutExample[1790:70b] current constraints (
"<NSLayoutConstraint:0x8ad95c0 V:[_UILayoutGuide:0x8ad8d40]-(127)-[UILabel:0x8ad7880]>",
"<_UILayoutSupportConstraint:0x8a6d3f0 V:[_UILayoutGuide:0x8ad8d40(20)]>",
"<_UILayoutSupportConstraint:0x8aaf250 V:|-(0)-[_UILayoutGuide:0x8ad8d40] (Names: '|':UIView:0x8ad8c90 )>",
"<NSIBPrototypingLayoutConstraint:0x8ad9c40 'IB auto generated at build time for view with ambiguity' V:[UILabel:0x8ad7880(21@251)] priority:251>"
)
2014-07-04 21:11:56.943 AutoLayoutExample[1790:70b] current constraints (
"<NSLayoutConstraint:0x8ad9670 H:|-(179)-[UILabel:0x8ad7880] (Names: '|':UIView:0x8ad8c90 )>",
"<NSIBPrototypingLayoutConstraint:0x8ad9c10 'IB auto generated at build time for view with ambiguity' H:[UILabel:0x8ad7880(42@251)] priority:251>"
)
2014-07-04 21:11:56.944 AutoLayoutExample[1790:70b] current constraints (
"<NSLayoutConstraint:0x8ad95c0 V:[_UILayoutGuide:0x8ad8d40]-(127)-[UILabel:0x8ad7880]>",
"<_UILayoutSupportConstraint:0x8a6d3f0 V:[_UILayoutGuide:0x8ad8d40(20)]>",
"<_UILayoutSupportConstraint:0x8aaf250 V:|-(0)-[_UILayoutGuide:0x8ad8d40] (Names: '|':UIView:0x8ad8c90 )>",
"<NSIBPrototypingLayoutConstraint:0x8ad9c40 'IB auto generated at build time for view with ambiguity' V:[UILabel:0x8ad7880(21@251)] priority:251>"
)

size信息部分是由IB自动生成的,但是它们的priority只有251,而不是之前的1000(required)了。

只指定位置,对比Default 和 PlaceHolder的 constraints,可以看到,在使用Default时,IB给自动加了NSContentSizeLayoutConstraint;在使用Placeholder时,IB自动生成了NSIBPrototypingLayoutConstraint,因为我们使用了PlaceHolder,并且size都是0,所以IB已经无法知道size信息了,为了避免ambiguity就只能自动加了。

我们在使用custom view时,需要指定intrinsic size为placeholder,那我们应该怎么解决IB自动添加ambiguity的constraint的问题呢?

事实上,如果我们的view是个custom view的话,IB是不会自动添加ambity的constraint,IB会添加NSContentSizeLayoutConstraint,然后在runtime时调用custom view 的intrinsicContentSize来知道view应该有多大。

还有继续说说intrinsicContentSize,事实上它不是一个人在战斗,其他的constraint只有一个priority,但是intrinsicContentSize有两个,分别叫Content Hugging Priority和Content Compression Resistancy Priority。 Content Hugging Priority控制当view frame>intrinsicContentSize时,是不是要缩小view 的size;而Content Compression Resistancy Priority控制当view frame<intrinsicContentSize时, 要不要截断content,保持view frame size。

举例来说,如果我有个UILabel,开始Title为“Label”,设置Width constraint 为42@500,设置Content Hugging Priority为1000, 设置Content Compression Resistancy Priority为1。如果我在runtime时改动Title为“S”,那整个UILabel的size都被缩小到只能容下5,因为这时frame size大于IntrinsicContentSize,Content Hugging Priority为1000,要比width constraint高,所以应该是Content Hugging 起作用;如果我把Title改为“325ioqukejgakshgkjashdgjka”,那这个UILabel的size会变为42,内容被截断为“32...”,因为这时frame size比IntrinsicContentSize小,Content Compression Resistancy Priority只有1,width constraint起作用,将宽度设置为42。

一个使用AutoLayout的有趣Bug

删除CenterY之前,IB知道X和Y 位置信息,因此系统给加的是ContentSizeLayoutConstraint,但删除之后,IB无法确定其Y方向的信息,生成了PrototypingLayoutConstraint。但为什么一个只有251的priority的PrototypingLayoutConstraint不会clip label呢?那我们就需要更多的了解PrototypingLayoutConstraint了。

//Before
2014-07-05 23:29:40.068 AutoLayoutExample[2035:70b] current constraints (
"<NSLayoutConstraint:0x8b44c20 H:|-(10)-[UILabel:0x8b450f0] (Names: '|':UITableViewCellContentView:0x8b453e0 )>",
"<NSContentSizeLayoutConstraint:0x8b37520 H:[UILabel:0x8b450f0(42)] Hug:251 CompressionResistance:750>"
) //After
2014-07-05 23:32:19.251 AutoLayoutExample[2062:70b] current constraints (
"<NSLayoutConstraint:0x8b66a10 H:|-(10)-[UILabel:0x8b664d0] (Names: '|':UITableViewCellContentView:0x8b66210 )>",
"<NSIBPrototypingLayoutConstraint:0x8b521f0 'IB auto generated at build time for view with ambiguity' H:[UILabel:0x8b664d0(42@251)] priority:251>"
)

Notes of learning AutoLayout的更多相关文章

  1. Machine Learning Algorithms Study Notes(3)--Learning Theory

    Machine Learning Algorithms Study Notes 高雪松 @雪松Cedro Microsoft MVP 本系列文章是Andrew Ng 在斯坦福的机器学习课程 CS 22 ...

  2. 【转载】 DeepMind用ReinforcementLearning玩游戏

    原文地址: https://blog.csdn.net/wishchin/article/details/42425145 原文 :  http://dataunion.org/?p=639 1.引言 ...

  3. DeepMind用ReinforcementLearning玩游戏

    原文 :  http://dataunion.org/?p=639 1.引言 说到机器学习最酷的分支,非Deep learning和Reinforcement learning莫属(以下分别简称DL和 ...

  4. Machine Learning Algorithms Study Notes(2)--Supervised Learning

    Machine Learning Algorithms Study Notes 高雪松 @雪松Cedro Microsoft MVP 本系列文章是Andrew Ng 在斯坦福的机器学习课程 CS 22 ...

  5. Machine Learning Algorithms Study Notes(1)--Introduction

    Machine Learning Algorithms Study Notes 高雪松 @雪松Cedro Microsoft MVP 目 录 1    Introduction    1 1.1    ...

  6. rt-thread learning notes

    rt-thread learning notes 2018-01-15 > 001 具有相同优先级的线程,每个线程的时间片大小都可以在初始化或创建该线程时指定 rt_thread_t rt_th ...

  7. (zhuan) Notes on Representation Learning

    this blog from: https://opendatascience.com/blog/notes-on-representation-learning-1/   Notes on Repr ...

  8. Mybatis Learning Notes 1

    Mybatis Learning Notes 主要的参考是博客园竹山一叶的Blog,这里记录的是自己补充的内容 实体类属性名和数据库不一致的处理 如果是实体类的结果和真正的数据库的column的名称不 ...

  9. Rust learning notes

    Rust learning notes Rust Version 1.42.0 $ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs ...

随机推荐

  1. 阿里云oss上传图片

    1.首先我们要下载阿里云oss的sdk包:(可以下载原版的,改过的通用版在本人的百度云,嘎嘎嘎~) 2.下载好之后放到项目文件目录里面 3.要在需要的控制器引用这个sdk文件例如: include(& ...

  2. 今日随笔:scrollTop与overflow

    今天想写一个页面一加载滚动条就自动滚到底部的效果,结果在IE上实现成功了,chrome上完全没反应,最后测试了一下,居然是因为css文件中,html,body都写了overflow:auto这一语句, ...

  3. Sql Server2005新特性及性能

    举几个例子来简单说明 这些例子我引用了Northwind库. 1. TOP 表达式 SQL Server 2000的TOP是个固定值,是不是觉得不爽,现在改进了. --前n名的订单declare @n ...

  4. [书]WALL·E、龙与地下铁、中国美丽的故事、故事新编、四十自述、书虫、人工智能、大话数据结构

    下午有时间,逛了逛了书城,看到了一些书.在这里总结一些自己的感受.   一.<龙与地下铁>     这本书是我首先看到的,就在靠前的新书区.是小说,我没看里面的内容,但是被书封皮的宣传文案 ...

  5. Spring RabbitMq

    spring-rabbitmq.xml文件内容如下: <?xml version="1.0" encoding="UTF-8"?><beans ...

  6. Displaying Window In Center In Oracle Forms 6i

    Center window automatically  in Oracle Forms 6i, use the following procedure by passing window name ...

  7. Install Google Pinyin on Ubuntu 14.04

    Install Google Pinyin on Ubuntu 14.04 I've been spending more and more time on Ubuntu and I'm not us ...

  8. (转载)5分钟安装Linux系统到U盘

    一.工具 使用 LinuxLive USB Creator 下载地址:http://xz2.cr173.com//soft/LinuxLiveusb.zip 二.操作步骤 1.下载linux系统镜像, ...

  9. 【转载】CSS position属性和实例应用

    目前几乎所有主流的浏览器都支持position属性("inherit"除外,"inherit"不支持所有包括IE8和之前版本IE浏览器,IE9.IE10还没测试 ...

  10. 当 IDENTITY_INSERT 设置为 OFF 时,不能为表‘XXX’中的标识列插入显式值。

    在创建事务复制时,很多时候不一定使用快照进行初始化,而是使用备份还原初始化.当对有标识列(即identity的自增列)的表进行复制的时候,使用备份还原初始化搭建起来的复制常常就会报错,即:当 IDEN ...