Swift - 伸缩优先级详解(Content Hugging、Content Compression Resistance)
作者:hangge | 2017-08-10 08:10
一、基本概念介绍
1,固有内容尺寸(intrinsic content size)
- 在开发中,有的控件或视图其本身就自带大小。这些控件能通过自己显示的内容计算出需要的 Size,这个自动计算出来 Size 就叫该控件的固有内容尺寸(intrinsic content size)。
- 比如 UIButton、UILabel 控件,我们设置完显示文字后,它就能根据字符串长度自动计算出宽高尺寸。同样情况的还有 UIImageView。
2,约束优先级
- 在没有 AutoLayout 的时候,我们通过 init(frame: CGRect) 方式来指定 UIView 的位置和大小。
- 而使用 AutoLayout 的时候,则通过约束来确定 UIView 的位置和大小。
- 为了解决多个约束冲突的问题,在 Autolayout 中每个约束都有一个优先级, 优先级的范围是 1 ~ 1000。创建一个约束,其默认的优先级是最高的 1000。
- 有了优先级,系统就可以通过比较两个“相互冲突的约束”的优先级,从而忽略低优先级的某个约束,达到正确布局的目的。
3,伸缩优先级
(1)对于像 UILabel、UIButton、UIImage 等具有固有内容尺寸的控件,我们可以只为其指定位置,它们会自动根据 intrinsic content size 显示相应的大小。
(2)通常情况下,这种不指定尺寸的布局不会出现问题。但在某些情况下,比如两个 UILabel 布局互相影响的话,就会造成组件间的 Intrinsic 冲突。(下面会通过样例演示)
(3)要解决冲突,就要用到 UIView 自带的模糊约束:content Hugging 和 content Compression Resistance 了。我们需要做的就是设置这两个约束的优先级,它们具体功能如下:
- Content Hugging Priority:表示一个控件“抗拉伸”的优先级。优先级越高,越不容易被拉伸,默认是:251。
- Content Compression Resistance Priority:表示一个控件“抗压缩”的优先级。优先级越高,越不容易被压缩,默认是:750。
二、Content Hugging Priority / Content Compression Resistance Priority 使用
1,Intrinsic 冲突样例
(1)假设我们需要实现如下列表,左侧显示文章标题,右侧显示日期。
(2)AutoLayout 布局的话,首先在单元格内部拖如两个 UILabel,并设置好相关样式属性。
(3)然后我们对标题 Label 设置上下左右 4 个约束。
(4)而对于日期 Label 则设置上下右 3 个约束。
(5)这两个标签我们都没设置尺寸约束,想让它们根据内容自己设置大小。但上面的约束添加完会发现系统提示有约束冲突错误:
(6)而程序运行后的效果如下,与我们想要的效果不一样。
2,问题原因
由于默认情况下,两个 UILabel 的抗拉伸、抗压缩优先级都是一样的。当单元格的空间不足以完全显示出标题和日期内容时,系统就不知道该压缩哪个 Label 的宽度。又或者空间充裕时,系统不知道该拉伸哪个 Label 的宽度。
3,解决办法
(1)我们希望在空间不足的情况下,优先压缩标题 Label 的宽度,那么可以将其抗压缩优先级调低,改成:749。
(2)而在空间充足的情况下,同样优先拉伸标题 Label 的宽度,那么同样将其抗拉伸优先级调低,改成:250。
(3)再次运行程序,便发现列表内容显示正常了。
全部评论(0)