iOS AutoLayout 约束 `lessThanOrEqualToConstant` 不起作用

iOS AutoLayout constraint `lessThanOrEqualToConstant` doesn't work

我在 UIStackView.

中遇到 UIView 的自动布局约束问题

我的目标是创建视图:

private static func makeSpace(with value: CGFloat) -> UIView {
    let view = UIView()
    view.translatesAutoresizingMaskIntoConstraints = true

    let heightConstraint =  view.heightAnchor.constraint(lessThanOrEqualToConstant: value)
    heightConstraint.priority = UILayoutPriorityDefaultHigh

    NSLayoutConstraint.activate([
        view.widthAnchor.constraint(equalToConstant: 295),
        heightConstraint
    ])

    return view
}

我想将此作为排列的子视图添加到 UIStackView 作为其他 UIStackView 排列的子视图之间的 space。

当我使用可视化检查器检查这些视图时,我的 space 视图的高度为 0。虽然,当我将约束更改为 equalToConstant 时,高度计算正确。

我想使用 lessThanOrEqualToConstant 允许这些 space 缩小,以防屏幕布局太小而无法以适当的尺寸容纳它们。

还有其他人遇到过这个问题吗?

看到这个布局错误发生在小于约束的情况下

但是像 UILabel 一样可以调整顶部和底部的大小

代码有效,因为 0 实际上小于或等于 295。如果您希望它小于或等于 295,具体取决于堆栈中的其他视图,您需要另一个约束,告诉它在可能的情况下扩展到 295:

private static func makeSpace(with value: CGFloat) -> UIView {
    let view = UIView()
    view.translatesAutoresizingMaskIntoConstraints = true

    // this keeps it under the value, we want this to be enforced, so priority stays `required`
    let heightConstraint1 =  view.heightAnchor.constraint(lessThanOrEqualToConstant: value)

    // this constraint will drive the size (the other one is just correcting it)
    let heightConstraint2 =  view.heightAnchor.constraint(equalToConstant: value)
    // modify this priority according to compression resistance of the other views
    heightConstraint2.priority = UILayoutPriority(rawValue: 240)

    NSLayoutConstraint.activate([
        view.widthAnchor.constraint(equalToConstant: 295),
        heightConstraint1,
        heightConstraint2
    ])

    return view
}

第一个约束将 space 保持在 value 之下(例如 295)。此约束必须具有 required 优先级,因为您不想以任何方式扩展此高度。

第二个约束告诉它保持高度等于 value。但它的优先级较低。所以其他约束可以覆盖它。如果发生这种情况,自动布局系统将尝试尽可能接近实现它 - 所以如果它不能是 295,但它可以是 230,那将会发生。

旁注:

如果您不关心将其扩展到比 value 更大的值(例如 295),那么您根本不需要第一个约束。我把它放在那里是因为我认为这是必须保留的 space 的限制。

另一个旁注:

CompressionResistancePriorityContentHuggingPriority 适用于具有固有大小的视图,不适用于 UIView.

**//1** 

 let child = UIView()
  child.translatesAutoresizingMaskIntoConstraints = false
  child.backgroundColor = .red
  view.addSubview(child)


**//2**

  child.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
  child.bottomAnchor.constraint(equalTo:     view.safeAreaLayoutGuide.bottomAnchor).isActive = true
  child.widthAnchor.constraint(equalToConstant: 128).isActive = true
  child.centerXAnchor.constraint(equalTo:   view.safeAreaLayoutGuide.centerXAnchor).isActive = true