我在苹果文档中找不到关于Cocoa Autolayout内容拥抱和抗压缩之间差异的明确答案。

有人能解释一下它们的用法和区别吗?


当前回答

内容拥抱和内容抗压缩优先级适用于那些可以根据进入的内容计算自身大小的元素。

苹果文档:

其他回答

如果view.intrinsicContentSize.width != NSViewNoIntrinsicMetric,那么自动布局会创建一个特殊的NSContentSizeLayoutConstraint类型的约束。这个约束就像两个正常的约束:

需要视图的约束。width <= view.intrinsicContentSize.width具有水平拥抱优先级,和 需要视图的约束。width >= view.intrinsicContentSize.width,具有水平抗压缩优先级。

在Swift中,使用iOS 9的新布局锚,你可以像这样设置等价的约束:

let horizontalHugging = view.widthAnchor.constraint(
    lessThanOrEqualToConstant: view.intrinsicContentSize.width)
horizontalHugging.priority = view.contentHuggingPriority(for: .horizontal)

let horizontalCompression = view.widthAnchor.constraint(
    greaterThanOrEqualToConstant: view.intrinsicContentSize.width)
horizontalCompression.priority = view.contentCompressionResistancePriority(for: .horizontal)

类似地,如果view.intrinsic contentsize .height != NSViewNoIntrinsicMetric,那么自动布局会创建一个NSContentSizeLayoutConstraint,它就像视图高度的两个约束。在代码中,它们看起来是这样的:

let verticalHugging = view.heightAnchor.constraint(
    lessThanOrEqualToConstant: view.intrinsicContentSize.height)
verticalHugging.priority = view.contentHuggingPriority(for: .vertical)

let verticalCompression = view.heightAnchor.constraint(
    greaterThanOrEqualToConstant: view.intrinsicContentSize.height)
verticalCompression.priority = view.contentCompressionResistancePriority(for: .vertical)

你可以通过打印view看到这些特殊的NSContentSizeLayoutConstraint实例(如果它们存在的话)。布局运行后的约束。例子:

label.constraints.forEach { print($0) }

// Output:
<NSContentSizeLayoutConstraint:0x7fd82982af90 H:[UILabel:0x7fd82980e5e0'Hello'(39)] Hug:250 CompressionResistance:750>
<NSContentSizeLayoutConstraint:0x7fd82982b4f0 V:[UILabel:0x7fd82980e5e0'Hello'(21)] Hug:250 CompressionResistance:750>

看看这个关于自动布局的视频教程,他们解释得很仔细

内容拥抱优先级就像放置在视图周围的橡皮筋。 优先级值越高,橡皮筋越强,它就越想拥抱它的内容大小。 优先级值可以想象成橡皮筋的“强度”

内容压缩阻力是指一个视图“抵抗”变小的程度 阻力优先级值较高的视图将抗压缩。

内容拥抱和内容抗压缩优先级适用于那些可以根据进入的内容计算自身大小的元素。

苹果文档:

假设你有一个文本为“Click Me”的按钮。这个按钮的宽度应该是多少?

首先,你肯定不希望按钮比文本小。否则,文本将被剪切。这是抗水平压缩的优先级。

其次,你不希望按钮比实际需要的要大。一个按钮,看起来像这样 , [           点击我           ], 显然太大了。你想让按钮“拥抱”它的内容而没有太多的填充。这是水平内容拥抱优先级。对于按钮来说,它不如水平抗压缩优先级强。