在两个视图之间添加尾随约束

Add trailing constraint between two views

我遇到了一个奇怪的行为

我以编程方式在 'UISlider' 和 'UILabel' 之间添加了一个尾随约束,它看起来像这样:

NSLayoutConstraint *timeLabelTrailing = [NSLayoutConstraint
                                             constraintWithItem:_timeLbl
                                             attribute:NSLayoutAttributeTrailing
                                             relatedBy:NSLayoutRelationEqual
                                             toItem:_seekBar
                                             attribute:NSLayoutAttributeTrailing
                                             multiplier:1
                                             constant:0];

    [timeLabelTrailing setActive:true];
    [self layoutIfNeeded];

并且 'UILabel' 尾随与 'UISlider' 尾随不匹配。

我尝试在 'UILabel' 和 'UIViewControoler' 视图之间做同样的事情并且它工作得很好,但是对于 'UISlider' 它出错了。

附上一些来自 ViewDebugger 的照片:

滑块

标签

这是因为您将它们放在了堆栈视图中! 因此 stackview 正在抑制其他约束。

我怎么知道它被抑制了?

viewdebugger 是一个非常强大的工具,但它的大部分功能都是未知的。

右边约束的颜色传达意思。

  • 深黑色约束正在产生影响。
  • 浅灰色约束被忽略是因为被更高的优先级抑制或约束之间的冲突意味着布局引擎将自行决定。这个决定的行为是不可预测的。

FWIW 灰色和黑色约束都是 活动的 ,但并非每个活动约束都得到 应用 。例如您可以对标签的宽度有数百个限制,每个限制都有不同的优先级。虽然它们都处于活动状态,但除了具有最高优先级的约束外,它们将被忽略。

如您所见☝️label.trailing = self.trailing @1000 被忽略了。当您忽略“1000”的优先级时,我非常确定调试器正在向您转储警告,但您没有在问题中提及它们。

长话短说,当您将东西放在堆栈视图中时,您不应该自己添加太多约束。

  • 'position' 相关的约束应该尽量避免。
  • 'size' 相关约束稍微可以接受。

我想你可能需要的是

stackView.alignment = .trailing

并确保删除其他尾随约束。

如果您希望滑块拉伸到堆栈视图的整个宽度,则将其限制为堆栈视图的宽度。标签从其 intrinsicContentSize 获取其宽度,这很好。

TBH 我不确定这是否是最好的方法,但我认为它可行。如果有人知道更好的方法,请发表评论。