I have to UILabel with dynamic height. I want to set it superview height equal to max of UILabel heights.
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")
}
}
If I set leftRow.botton.equalTo(superview.bottom)
and rightRow.botton.equalTo(superview.bottom)
it's working. But I think is not a good way. And I don't understand why setContentHuggingPriority
not helped me to solve this problem.
Content hugging leads more likely to squeeze your labels. What you want is the height of the labels to be more respected. So you'd rather use compression resistance priority. However you actually need neither of those.
Since you're setting your constraints programatically, you'll need to set translatesAutoresizingMaskIntoConstraints
to false
for your labels as well:
leftRow.translatesAutoresizingMaskIntoConstraints = false
rightRow.translatesAutoresizingMaskIntoConstraints = false
The bottom constraint is actually a good start, but you don't want to fit the height of the smaller label unnecessarily to the height of the bigger label. So you would want to add a constraint that is "less than or equal to the bottom anchor":
make.bottom.lessThanOrEqualTo(self.snp.bottom)
If you want to use lazy variables you'll have to change the way there being initialized. The way you've written it, it initializes the variables right away when initializing the class. But you only want them to be initialized when they're used the first time. For that you need to write it like this:
private lazy var leftRow: UILabel = {
return UILabel()
}()
private lazy var rightRow: UILabel = {
return UILabel()
}()
However in your case you don't need lazy loading, so you can initialize them directly:
private let leftRow = UILabel()
private let rightRow = UILabel()
Since you're using layout constraints, you don't need to call sizeToFit
on the labels. It doesn't do anything.
Calling layoutIfNeeded()
within the init doesn't do anything either since it will be called anyway once you add ComponentCell
as a subview to another view.