iOS AutoLayout约束`lessThanOrEqualToConstant`不起作用

时间:2017-12-13 09:55:57

标签: ios swift autolayout uistackview

我在UIView内的UIStackView的自动布局限制存在问题。

我的目标是创建一个视图:

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个已排列的子视图之间的空格。

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

我想使用lessThanOrEqualToConstant允许这些空格缩小,以防屏幕布局太小而不适合它们。

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

3 个答案:

答案 0 :(得分:0)

在使用少于Constaint的布局设置中查看此错误 enter image description here

但顶部和底部可调整大小,如UILabel,它可以enter image description here

答案 1 :(得分:0)

代码有效,因为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
}

第一个约束使value下的空间保持不变(例如295)。此约束必须具有required优先级,因为您不希望以任何方式扩展此高度。

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

旁注:

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

另一方面说明:

CompressionResistancePriorityContentHuggingPriority适用于内在大小的视图,不适用于UIView

答案 2 :(得分:0)

**//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