一、基本概念介绍

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


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


2,约束优先级



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



Swift Din字体_swift




3,伸缩优先级


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


Swift Din字体_优先级_02




UILabel 布局互相影响的话,就会造成组件间的  Intrinsic 冲突。(下面会通过样例演示)



UIView 自带的模糊约束: content Hugging 和  content Compression Resistance


  • Content Hugging Priority:表示一个控件“抗拉伸”的优先级。优先级越高,越不容易被拉伸,默认是:251
  • Content Compression Resistance Priority:表示一个控件“抗压缩”的优先级。优先级越高,越不容易被压缩,默认是:750



Swift Din字体_约束优先级_03




二、Content Hugging Priority / Content Compression Resistance Priority 使用

1,Intrinsic 冲突样例


(1)假设我们需要实现如下列表,左侧显示文章标题,右侧显示日期。


Swift Din字体_swift_04



AutoLayout 布局的话,首先在单元格内部拖如两个  UILabel,并设置好相关样式属性。


Swift Din字体_Swift Din字体_05



Label 设置上下左右  个约束。


Swift Din字体_swift_06


 


Label 则设置上下右  3


Swift Din字体_约束优先级_07



(5)这两个标签我们都没设置尺寸约束,想让它们根据内容自己设置大小。但上面的约束添加完会发现系统提示有约束冲突错误:


Swift Din字体_swift_08



(6)而程序运行后的效果如下,与我们想要的效果不一样。


Swift Din字体_控件_09



2,问题原因



UILabel 的抗拉伸、抗压缩优先级都是一样的。当单元格的空间不足以完全显示出标题和日期内容时,系统就不知道该压缩哪个  Label 的宽度。又或者空间充裕时,系统不知道该拉伸哪个  Label 的宽度。





3,解决办法



Label 的宽度,那么可以将其抗压缩优先级调低,改成: 749



Label 的宽度,那么同样将其抗拉伸优先级调低,改成: 250



Swift Din字体_控件_10





(3)再次运行程序,便发现列表内容显示正常了。