返回 导航

Swift

hangge.com

Swift - 伸缩优先级详解(Content Hugging、Content Compression Resistance)

作者:hangge | 2017-08-10 08:10

一、基本概念介绍

1,固有内容尺寸(intrinsic content size)

  • 在开发中,有的控件或视图其本身就自带大小。这些控件能通过自己显示的内容计算出需要的 Size,这个自动计算出来 Size 就叫该控件的固有内容尺寸(intrinsic content size)。
  • 比如 UIButtonUILabel 控件,我们设置完显示文字后,它就能根据字符串长度自动计算出宽高尺寸。同样情况的还有 UIImageView

2,约束优先级

  • 在没有 AutoLayout 的时候,我们通过 init(frame: CGRect) 方式来指定 UIView 的位置和大小。
  • 而使用 AutoLayout 的时候,则通过约束来确定 UIView 的位置和大小。
  • 为了解决多个约束冲突的问题,在 Autolayout 中每个约束都有一个优先级, 优先级的范围是 1 ~ 1000。创建一个约束,其默认的优先级是最高的 1000
  • 有了优先级,系统就可以通过比较两个“相互冲突的约束”的优先级,从而忽略低优先级的某个约束,达到正确布局的目的。

3,伸缩优先级

(1)对于像 UILabelUIButtonUIImage 等具有固有内容尺寸的控件,我们可以只为其指定位置,它们会自动根据 intrinsic content size 显示相应的大小。

(2)通常情况下,这种不指定尺寸的布局不会出现问题。但在某些情况下,比如两个 UILabel 布局互相影响的话,就会造成组件间的 Intrinsic 冲突。(下面会通过样例演示)

(3)要解决冲突,就要用到 UIView 自带的模糊约束:content Huggingcontent 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)

回到顶部