如何将UIView高度设置为等于两个子视图UILabel的最大值?

时间:2019-04-14 08:37:13

标签: ios swift uilabel nslayoutconstraint snapkit

我必须使用动态高度的UILabel。我想将其superview高度设置为等于UILabel高度的最大值。

class ComponentCell: UIView {
  private lazy var leftRow: UILabel = UILabel()
  private lazy var rightRow: UILabel = UILabel()

  init(leftValue: String, rightValue: String) {
    super.init(frame: .zero)
    leftRow.backgroundColor = .red
    leftRow.numberOfLines = 0
    leftRow.lineBreakMode = .byWordWrapping
    leftRow.text = leftValue
    rightRow.text = rightValue
    rightRow.backgroundColor = .yellow
    rightRow.numberOfLines = 0
    rightRow.lineBreakMode = .byWordWrapping
    self.addSubview(self.leftRow)
    self.addSubview(self.rightRow)
    leftRow.sizeToFit()
    rightRow.sizeToFit()
    leftRow.setContentHuggingPriority(.required, for: .vertical)
    rightRow.setContentHuggingPriority(.required, for: .vertical)
    self.translatesAutoresizingMaskIntoConstraints = false
    self.leftRow.snp.makeConstraints { make in
      make.top.equalToSuperview()
      make.left.equalToSuperview()
      make.width.equalToSuperview().dividedBy(2)
    }
    self.rightRow.snp.makeConstraints { make in
      make.top.equalToSuperview()
      make.right.equalToSuperview()
      make.width.equalToSuperview().dividedBy(2)
    }
    self.layoutIfNeeded()
  }

  required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }
}

如果我设置了leftRow.botton.equalTo(superview.bottom)rightRow.botton.equalTo(superview.bottom),则它可以正常工作。但是我认为这不是一个好方法。而且我不明白为什么setContentHuggingPriority不能帮助我解决这个问题。

1 个答案:

答案 0 :(得分:3)

内容拥抱

内容拥抱会更容易挤压您的标签。您想要的是标签的高度要更受尊重。因此,您宁愿使用抗压缩优先级。但是,您实际上不需要这些。

布局约束

由于您是通过编程方式设置约束的,因此还需要将标签的translatesAutoresizingMaskIntoConstraints设置为false

leftRow.translatesAutoresizingMaskIntoConstraints = false
rightRow.translatesAutoresizingMaskIntoConstraints = false

底部约束实际上是一个好的开始,但是您不想不必要地使较小标签的高度适合较大标签的高度。因此,您需要添加一个“小于或等于底部锚点”的约束:

make.bottom.lessThanOrEqualTo(self.snp.bottom)

惰性变量

如果要使用惰性变量,则必须更改初始化方式。编写方式,它在初始化类时立即初始化变量。但是,您只希望在首次使用它们时对其进行初始化。为此,您需要这样写:

private lazy var leftRow: UILabel = {
    return UILabel() 
}()
private lazy var rightRow: UILabel = {
    return UILabel() 
}()

但是,在您的情况下,您不需要延迟加载,因此可以直接对其进行初始化:

private let leftRow = UILabel()
private let rightRow = UILabel()

其他

由于使用的是布局约束,因此无需在标签上调用sizeToFit。它什么也没做。

在init中调用layoutIfNeeded()不会执行任何操作,因为一旦将ComponentCell作为子视图添加到另一个视图后,它将被调用。