ChatGPT解决这个技术问题 Extra ChatGPT

Cocoa Autolayout:内容拥抱与内容压缩阻力优先级

我在 Apple 文档中找不到关于 Cocoa Autolayout 内容拥抱和抗压缩性区别的明确答案。

有人可以解释他们的用法和区别吗?

生命的一大奥秘就是为什么他们不把它简单地称为“扩张抵抗”。两种品质无非就是“抗膨胀”和“抗压”。 “拥抱”这个词太疯狂了。
如果你有太多空间,那么 content-hugging: 会反对留白。它只会迫使视图绕过你。但是如果您没有太多空间,而是没有太多空间,那么 content-compressions-resistance 会阻止您的视图无法显示其所有内容,例如标签会被截断。

n
ncica

概念的快速总结:

拥抱 => 内容不想增长

抗压性 => 内容不想收缩

例子:

假设你有一个这样的按钮:

[       Click Me      ]

并且您已将边缘固定到优先级为 500 的更大超级视图。

然后,如果拥抱优先级 > 500,它将如下所示:

[Click Me]

如果拥抱优先级 < 500,它将如下所示:

[       Click Me      ]

如果 superview 现在缩小了,如果 Compression Resistance 优先级 > 500,它看起来像这样

[Click Me]

否则,如果抗压优先级 < 500,则可能如下所示:

[Cli..]

如果它不能像这样工作,那么你可能还有其他一些限制正在搞乱你的好工作!

例如,您可以将其固定到优先级为 1000 的超级视图。或者您可以设置宽度优先级。如果是这样,这可能会有所帮助:

编辑器 > 大小以适合内容


如果拥抱优先级 == 500 会怎样?
我假设(但这通常不是一个好主意)它会像典型的舍入行为一样被视为 >500。虽然没有测试过。
您很可能会在运行时收到“无法同时满足约束”警告
@bradley.ayers 对于 MaxDesyatov 的评论,只有当您有与必需优先级 (1000) 冲突的约束时才会发生这种情况。如果两个较低优先级的约束发生冲突,则解决方案不明确,因此自动布局引擎只会选择一个有效的解决方案,这就是您将看到的(没有警告)。显然这不好,因为现在由 Auto Layout 引擎的内部实现来选择布局的外观,理论上这可能会从一个 iOS 版本更改为下一个版本!
内容拥抱优先级默认为250,抗内容压缩默认为750。那为什么要使用500呢?
o
onmyway133

看看这个视频tutorial about Autolayout,他们仔细解释

https://i.stack.imgur.com/6GelD.png


@fatuhoku 你能再看一遍吗,这个视频是免费的
拥抱与抵抗的讨论大约在视频中的 13 点 15 分开始。
@onmyway133 这是完美的视频,但不幸的是,没有 Ray 是如何使用它的示例。
@MatrosovAlexander 我认为一个非常实用的例子是带有自动布局的动态单元格高度fantageek.com/1468/…
他在 18:05 展示了如何使用抗压性
S
SparkyRobinson

https://i.stack.imgur.com/bTZMz.jpg

来源:@mokagio

内在内容大小 - 非常不言自明,但内容可变的视图知道其内容有多大,并通过此属性描述其内容的大小。具有固有内容大小的视图的一些明显示例是 UIImageViews、UILabels、UIButtons。

内容拥抱优先级 - 此优先级越高,视图越能抵抗大于其固有内容大小的增长。

内容压缩阻力优先级 - 此优先级越高,视图越能抵抗收缩小于其固有内容大小。

在这里查看更多解释:AUTO LAYOUT MAGIC: CONTENT SIZING PRIORITIES


插图很好,但至少可以说是误导。高层应该说“我不会(让我)成长”。子视图自行定义它不想通过其内容拥抱行为来成长。没有任何外力(如图示的手)阻止它生长。这是一个很大的区别。
我投票赞成只是因为我喜欢这个插图。
这就是我喜欢 Stack Overflow 的原因……Snowcrash 的描述加上 mokagio 的插图 = 对这些属性的最佳解释(包括 Apple 自己的文档)。
@Manuel 我不认为这是子视图和父视图。相反,矩形是视图,而人是隐式生成的系统约束,试图以设定的优先级实现所需的行为(拥抱或压缩阻力)。所以插图还是对的。
B
Bridger Maxwell

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

首先,您绝对不希望按钮小于文本。否则,文本将被剪切。这是水平抗压优先级。

其次,你不希望按钮比它需要的大。看起来像这样的按钮 [ Click Me ] 显然太大了。您希望按钮在没有太多填充的情况下“拥抱”其内容。这是横向内容拥抱优先级。对于一个按钮来说,它不如水平抗压优先级强。


r
rob mayoff

如果为 view.intrinsicContentSize.width != NSViewNoIntrinsicMetric,则自动布局创建类型为 NSContentSizeLayoutConstraint 的特殊约束。此约束的作用类似于 两个 普通约束:

要求 view.width <= view.intrinsicContentSize.width 具有水平拥抱优先级的约束,以及

要求 view.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.intrinsicContentSize.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.constraints 来查看这些特殊的 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>

不应该是:让verticalCompression = view.heightAnchor.constraint(greaterThanOrEqualToConstant: view.intrinsicContentSize.height)
是的,我犯了复制/粘贴错误。我已经纠正了。谢谢你让我知道。
d
dev gr

Content Hugging 和 Content Compression Resistence Priorities 适用于可以根据传入的内容本质上计算其大小的元素。

Apple docs

https://i.stack.imgur.com/xzqgz.png


我很困惑。对于未启用滚动的 textView。这是否意味着每个用户键入内在大小都会改变?
@Honey 我认为在设置正确的约束和禁用滚动的情况下,文本视图应该能够分辨出内在高度。
那没有回答我的问题。你的意思是如果我输入了很多,超过了 textView 的当前大小...... textView 会自动扩展并改变内在大小吗?
自己试试。给 textview 一个固定宽度并禁用滚动并检查所需的行为。有关更多答案,请参阅 stackoverflow.com/a/21287306/1526629
N
Naishta

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

Content Compression Resistance 是,视图“抵抗”变小的多少具有较高抵抗优先级值的视图会抵抗压缩。


a
ahmed

contentCompressionResistancePriority – 当没有足够的空间容纳所有内容时,具有最低值的视图会被截断intrinsicContentSize

contentHuggingPriority – 当有剩余空间要填充时,具有最低值的视图会扩展到其 intrinsicContentSize 之外


我现在一直记得这一点,从那以后就没有问题了。当没有足够的空间容纳元素时,阻力优先级很重要。当空间太大时,拥抱优先级很重要。

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅