iOS 自动布局忽略 "trailing space" 约束,而是使用 width/content 大小?
iOS autolayout disregarding "trailing space" constraint, using width/content size instead?
我有一个 UILabel
(副标题),我希望它有一个静态 X 原点,但延伸到它最近邻居的边缘。有一个按钮 ("Visit Link"),如果不需要,可以选择在 运行 时间从超级视图中删除。标签到按钮的约束优先级为1000,标签到superview容器的约束优先级为250:
但是,当我 运行 应用程序删除按钮时(通过 viewDidLoad
方法中的 .removeFromSuperview()
),通过视图调试我看到内容大小正在设置宽度标签,优先于我设置的约束。
我 期望 标签延伸到视图的边缘,但如您所见,约束是灰色的 - 我假设 (content size)
改为约束:
(content size)
约束的优先级是否高于我的 Trailing Space to: Superview
约束?我该如何更改它,因为它不是我定义的约束?
从第二个屏幕截图来看,一切似乎都在按预期进行。
我想提两件事:
- 始终尝试设置您的布局,使您的限制尽可能少。每个约束都会增加复杂性。
- 是的,标签的内容大小确实有更高的优先级。这就是标签未调整到最右边缘的原因,这很好。您看到的是标签的固有大小,这意味着 UIKit 知道应该绘制多大的标签,具体取决于字体、文本等。
为了让这个布局更稳健一点,我会更改标签的尾部 space 以便它具有优先级 1000
但 >= 0
.
这样,无论有没有访问 Link 按钮,布局都将有效,并且标签的内容大小(它的固有大小)将调整它的大小到它需要的任何长度,但不超过其父视图的右边缘。
希望对您有所帮助!
更新:写了一个简短的 post 关于为什么会出现这个内容大小以及为什么你应该利用它来发挥你的优势。
(content size)
约束由系统在运行时自动安装,优先级似乎在 250 到 750 之间。当我使用 250
或 251
作为我的 Trailing Space
约束,不起作用。
然而,将我的 Trailing Space
约束的优先级提高到 750
的 Xcode-titled High 优先级,允许它优先.所以 UILabel
宽度的默认值似乎下降 "somewhere in the middle."
Autolayout,你个傻子。
当您从视图层次结构中删除按钮时,也会删除涉及该按钮的任何约束。所以,剩下的就是优先级为 250 的父视图的尾随约束。
标签具有基于其内容的固有宽度。这意味着它的水平内容拥抱和抗压缩优先级开始发挥作用。它的内容拥抱优先级是251.
这意味着对于自动布局系统来说,视图的宽度不超过必要的宽度比保持其后缘与父视图的后缘相距 8 点更重要。
您或许应该提高尾随约束的优先级。您希望它小于按钮的尾随约束,以便在存在按钮的情况下不会发生冲突。您还希望它低于按钮的压缩阻力优先级,以便按钮不会被压扁以允许标签距超级视图 8 点。但是,除此之外,您希望它尽可能高。 (在假设的情况下,您只是简单地摆脱了存在按钮的可能性,您通常会要求该尾随约束,对吧?因此,它应该尽可能接近要求,而不会造成不良副作用。)
如果您的目标是部署到 iOS 9.0 或更高版本,您应该考虑为此布局使用 UIStackView
。它会为您处理一些事情,例如在隐藏或显示按钮时添加或删除适当的约束。
我有一个 UILabel
(副标题),我希望它有一个静态 X 原点,但延伸到它最近邻居的边缘。有一个按钮 ("Visit Link"),如果不需要,可以选择在 运行 时间从超级视图中删除。标签到按钮的约束优先级为1000,标签到superview容器的约束优先级为250:
但是,当我 运行 应用程序删除按钮时(通过 viewDidLoad
方法中的 .removeFromSuperview()
),通过视图调试我看到内容大小正在设置宽度标签,优先于我设置的约束。
我 期望 标签延伸到视图的边缘,但如您所见,约束是灰色的 - 我假设 (content size)
改为约束:
(content size)
约束的优先级是否高于我的 Trailing Space to: Superview
约束?我该如何更改它,因为它不是我定义的约束?
从第二个屏幕截图来看,一切似乎都在按预期进行。
我想提两件事:
- 始终尝试设置您的布局,使您的限制尽可能少。每个约束都会增加复杂性。
- 是的,标签的内容大小确实有更高的优先级。这就是标签未调整到最右边缘的原因,这很好。您看到的是标签的固有大小,这意味着 UIKit 知道应该绘制多大的标签,具体取决于字体、文本等。
为了让这个布局更稳健一点,我会更改标签的尾部 space 以便它具有优先级 1000
但 >= 0
.
这样,无论有没有访问 Link 按钮,布局都将有效,并且标签的内容大小(它的固有大小)将调整它的大小到它需要的任何长度,但不超过其父视图的右边缘。
希望对您有所帮助!
更新:写了一个简短的 post 关于为什么会出现这个内容大小以及为什么你应该利用它来发挥你的优势。
(content size)
约束由系统在运行时自动安装,优先级似乎在 250 到 750 之间。当我使用 250
或 251
作为我的 Trailing Space
约束,不起作用。
然而,将我的 Trailing Space
约束的优先级提高到 750
的 Xcode-titled High 优先级,允许它优先.所以 UILabel
宽度的默认值似乎下降 "somewhere in the middle."
Autolayout,你个傻子。
当您从视图层次结构中删除按钮时,也会删除涉及该按钮的任何约束。所以,剩下的就是优先级为 250 的父视图的尾随约束。
标签具有基于其内容的固有宽度。这意味着它的水平内容拥抱和抗压缩优先级开始发挥作用。它的内容拥抱优先级是251.
这意味着对于自动布局系统来说,视图的宽度不超过必要的宽度比保持其后缘与父视图的后缘相距 8 点更重要。
您或许应该提高尾随约束的优先级。您希望它小于按钮的尾随约束,以便在存在按钮的情况下不会发生冲突。您还希望它低于按钮的压缩阻力优先级,以便按钮不会被压扁以允许标签距超级视图 8 点。但是,除此之外,您希望它尽可能高。 (在假设的情况下,您只是简单地摆脱了存在按钮的可能性,您通常会要求该尾随约束,对吧?因此,它应该尽可能接近要求,而不会造成不良副作用。)
如果您的目标是部署到 iOS 9.0 或更高版本,您应该考虑为此布局使用 UIStackView
。它会为您处理一些事情,例如在隐藏或显示按钮时添加或删除适当的约束。