Autolayout中关于intrinsic content、相关优先级及其应用

来源:互联网 发布:windows 串口工具 编辑:程序博客网 时间:2024/06/06 00:12

Autolayout中关于intrinsic content、相关优先级及其应用

字数1495 阅读497 评论3 
关键词:   intrinsic content size(固有内容大小)、约束优先级、  Content Hugging Priority、  Content Compression Resistance Priority

理论

  • intrinsic content size: 有些控件能通过自己显示的内容计算出需要的Size,这个自动计算出来size就叫该控件的固有内容大小。这个大小是和需要显示的内容相关的。UIButton,UILabel就是具有固有内容大小属性的控件。UIButton可以根据它的title字符串长度和需要显示的image来计算需要的Size,UILabel可以根据它的text来计算。 

  • 约束优先级: 在Autolayout中每个约束都有一个优先级,在xib或storyboard中双击一个约束即可看到它的优先级。优先级的范围是1 ~ 1000。创建一个约束,默认的优先级是最高的1000 


约束优先级
  • Content Hugging Priority: 该优先级表示一个控件抗被拉伸的优先级。优先级越高,越不容易被拉伸,默认是251。

  • Content Compression Resistance Priority: 该优先级和上面那个优先级相对应,表示一个控件抗压缩的优先级。优先级越高,越不容易被压缩,默认是750

    这些优先级的绝对值意义不大,Autolayout怎么布局只取决于控件优先级的相对值,我们可以把固有内容的两个优先级也看做是约束,那么自动布局将按照一个简单的原则处理所有的约束:优先级高的,先满足(好像是废话,但可以用这个原则去解释Autolayout的行为) 

    现在还是很模糊,没关系,下面我们将通过实例来看看这条原则是怎么应用的。

实例

我们在View中添加了一个UILabel,并为其添加了三个约束:在竖直方向居中,距离左边屏幕145,距离右边屏幕145。为了看到UILabel的实际宽度,我们将Label的背景色置为灰色。 


其运行效果如下: 


从最后的显示效果来看,中间的Label被压缩了,来满足左右两个约束。
根据第一个图中标注的优先级,左右约束的优先级比固有内容相关的优先级要高,所以Autolayout布局的时候会优先满足左右两个约束。这时候:左边约束宽度(145) + 右边约束宽度(145) + Label的固有内容宽度 > 屏幕宽度。所以最后只能压缩Label显示的宽度。 

Content Compression Resistance Priority

这时候Label是被压缩的,我们就来演示一下Content Compression Resistance Priority这个优先级是如何影响控件的抗压缩特性的 

我们修改右边的约束优先级为700 


其运行效果如下: 


这时候UILabel控件的抗压缩约束优先级比右边约束优先级高,Autolayout先满足左边约束,然后满足UILable控件的固有内容Size的宽度,最后来调整右边约束的宽度。表现出来就是UILable抗压缩特性变强了,它更倾向于显示它固有内容Size。这时候被压缩的就是右边的约束。 

Content Hugging Priority

为了演示Label被拉伸的情况,我们将右边的约束优先级恢复为1000,并将左右约束的宽度都改为50。 

其运行效果如下: 


和压缩的时候类似,左右约束优先级比UILabel的Content Hugging Priority优先级高,并且此时:左边约束宽度(50) + 右边约束宽度(50) + Label的固有内容宽度 < 屏幕宽度。为了满足左右两个约束,就只有拉伸Label。
此时我们将右边约束的优先级变为240。 

其运行结果为: 


这时候UILabel控件的抗拉伸约束优先级比右边约束优先级高,Autolayout先满足左边约束,然后满足UILable控件的固有内容Size的宽度,最后来调整右边约束的宽度。表现出来就是UILable抗拉伸特性变强了,它更倾向于显示它固有内容Size。这时候被拉伸的就是右边的约束。 

实际应用

我们常常遇到的是类似下面的情况: 


TitleLabel的显示内容可能会很长,如果不能很好的设置约束就可能覆盖后面显示时间的Label。但显示时间的Label也应该是一个动态的长度。针对这种情况,我们在模拟器中来模拟一下。 



两个Label,前面是AddressLabel,后面是TimeLabel,为了不让两个Label覆盖,我们设定前后Label的水平间距>=10,没有调整过任何优先级。 

显示效果如下: 


这时候系统会默认调整前面Label的宽度,使其压缩,来满足后面Label能够完整显示,这应该是系统默认行为。这样看起来刚刚好,但如果我们的需求是时间在前面,并且需要完全显示。地址信息在后面,如果过长就显示省略号。那么使用上面的默认行为就不能满足要求。 

其运行结果为: 


这时候前面的TimeLabel会被默认压缩,不能满足要求。这时候我们就可以通过改变控件的抗压缩优先级来满足要求,我们可以把AddressLabel的抗压缩优先级改为740,比TimeLabel默认的750低,那么Autolayout就会去压缩AddressLabel,而使TimeLabel按照它固有内容的宽度显示。这就可以满足我们的要求了。 

来看一下最后的显示效果: 



0 0
原创粉丝点击