在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. 剑指offer——变态跳台阶

    题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级.求该青蛙跳上一个n级的台阶总共有多少种跳法. 问题分析 由于每次跳的阶数不确定,没有一个固定的规律,但是可以了解的是后一次跳 ...

  2. noi 8787 数的划分

    题目链接:http://noi.openjudge.cn/ch0206/8787/ 将整数n分成k份,且每份不能为空,任意两份不能相同(不考虑顺序). 简直跟分苹果一模一样. #include < ...

  3. Nginx的负载均衡 - 整体架构

    Nginx的负载均衡 - 整体架构 Nginx版本:1.9.1 我的博客:http://blog.csdn.net/zhangskd Nginx目前提供的负载均衡模块: ngx_http_upstre ...

  4. Spring 源码学习

    spring最核心的理念是IOC,包括AOP也要屈居第二,那么IOC到底是什么呢,四个字,控制反转 一.什么是Ioc/DI? IoC 容器:最主要是完成了完成对象的创建和依赖的管理注入等等. 先从我们 ...

  5. "Resuming debugger: error during debugging loop: TypeError: firstViewRangeElement is null"

    翻译过来:“重启调试器:错误调试期间循环:TypeError:firstViewRangeElement为空” 写了一个项目,其中使用到了上传图片的插件,在本地上传图片一切正常,发布到服务器却不正常了 ...

  6. Java 中文字符串编码之GBK转UTF-8

    写过两篇关于编码的文章了,以为自己比较了解编码了呢?! 结果今天又结结实实的上了一课. 以前转来转去解决的问题终归还是简单的情形.即iso-8859-1转utf-8,或者iso-8859-1转gbk, ...

  7. 文件上传和下载(可批量上传)——Spring(二)

    针对SpringMVC的文件上传和下载.下载用之前“文件上传和下载——基础(一)”的依然可以,但是上传功能要修改,这是因为springMVC 都为我们封装好成自己的文件对象了,转换的过程就在我们所配置 ...

  8. microstrip(微带线)、stripline(带状线) 指什么?

    带状线:走在内层(stripline/double stripline),埋在PCB内部的带状走线,如下图所示 蓝色部分是导体,绿色部分是PCB的绝缘电介质,stripline是嵌在两层导体之间的带状 ...

  9. 事务码 ListSchema:查看Cube星型结构Schema

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  10. 特征的Attribute Only选项

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...