iOS自动布局是否忽略“尾部空间”约束,而使用宽度/内容大小?

3
我有一个UILabel(副标题),我想让它的X起点是静态的,但延伸到它最近邻居的边缘。有一个按钮(“访问链接”),如果不需要,可以在运行时从其超级视图中删除。标签到按钮的约束优先级为1000,标签到父视图容器的约束优先级为250:

enter image description here

然而,当我在viewDidLoad方法中使用.removeFromSuperview()删除按钮并运行应用程序时,通过视图调试,我发现内容大小设置了标签的宽度,并优先于我设置的约束条件。 我期望标签延伸到视图的边缘,但是如您所见,该约束条件已变灰 - 我认为被(content size)约束条件所取代:

enter image description here

(内容大小)约束是否比我的Trailing Space to: Superview约束优先级更高?我该如何更改它,因为这不是我定义的约束?

3个回答

1
当您从视图层次结构中移除按钮时,也会移除涉及该按钮的任何约束。因此,剩下的只有优先级为250的到父视图的尾部约束。
标签具有基于其内容的内在宽度。这意味着其水平内容吸附和压缩阻力优先级发挥作用。其内容吸附优先级为251。
这意味着对于自动布局系统来说,使视图的宽度不要超过必要的大小比将其后缘保持在距离父视图后缘8个点更重要。
您应该增加尾部约束的优先级。您希望它小于按钮的尾部约束,以便在按钮存在的情况下不会发生冲突。您还希望它小于按钮的压缩阻力优先级,以便按钮不会被挤压以允许标签与父视图相距8个点。但是,除此之外,您希望它尽可能高。(在假设消除了按钮存在的可能性的情况下,通常会使该尾部约束为所需的,对吧?因此,它应该尽可能靠近所需而不会引起不良副作用。)
如果你的目标是部署到 iOS 9.0 或更高版本,你应该考虑使用 UIStackView 来进行布局。它会为你处理一些事情,比如在按钮隐藏或显示时添加或删除适当的约束条件。

我认为你说得完全正确 - 我正在进行实验(请看我的回答),当我给我的约束设置了250251的优先级时,它被覆盖了。然而,根据你的解释,我尝试了252,那就是神奇的临界点,它开始工作了。 - Craig Otis

0
从第二个屏幕截图来看,一切似乎都按照预期工作。
有两件事我想提一下:
  1. 始终尝试设置您的布局,使约束条件尽可能少。每个约束都会增加复杂性。
  2. 是的,标签的内容大小确实具有更高的优先级。这就是为什么标签没有调整大小到最右边的边缘,这是好的。您看到的是标签的内在大小,这意味着UIKit知道该如何绘制标签的大小,取决于字体、文本等。
为了使此布局更加健壮,我将更改标签的“Trailing space”,使其具有优先级1000但是>= 0
这样,无论是否存在“Visit Link”按钮,布局都将有效,并且标签的内容大小(其固有大小)将调整为需要的任何长度,但不超过其父视图的右侧边缘。
希望这可以帮助!

更新:我写了一篇关于为什么会出现这种内容大小以及为什么你应该利用它的优势的快速文章。


0

(内容大小)约束在运行时由系统自动安装,优先级似乎介于250和750之间。当我使用250251作为Trailing Space约束时,它不起作用。

然而,将我的Trailing Space约束的优先级提高到Xcode标题的High优先级750,可以使其优先。因此,UILabel的默认宽度似乎落在“中间位置”。

自动布局,你真傻。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接