Reputation: 669
I am having trouble setting up auto layout for UILabel and would like to get help on this.
In the picture, I have created yellow and green UILabels.
What I want to achieve is dynamically adjust the yellow UILabel height based on its content's number of lines, and anchor top of green box to anchor bottom of yellow box.
Currently, I have code as follow:
// Yellow UILabel
addSubview(captionLabel)
captionLabel.anchor(top: actionButtonsStackView.bottomAnchor, left: leadingAnchor, bottom: nil, right: trailingAnchor, paddingTop: 0, paddingLeft: 8, paddingBottom: 0, paddingRight: 8, width: 0, height: 0)
captionLabel.heightAnchor.constraint(greaterThanOrEqualToConstant: 0).isActive = true
// Green UILabel
addSubview(dateLabel)
dateLabel.anchor(top: captionLabel.bottomAnchor, left: leadingAnchor, bottom: bottomAnchor, right: trailingAnchor, paddingTop: 0, paddingLeft: 8, paddingBottom: 0, paddingRight: 8, width: 0, height: 0)
Note: the anchor function sets top, leading, bottom, and trailing constraints with respective paddings.
As you can see, the yellow UILabel takes up more space than it actually needs.
If I leave top constraint from green UILabel, the yellow box actually starts to work as I expect:
And the code for this looks like:
// Yellow UILabel
addSubview(captionLabel)
captionLabel.anchor(top: actionButtonsStackView.bottomAnchor, left: leadingAnchor, bottom: nil, right: trailingAnchor, paddingTop: 0, paddingLeft: 8, paddingBottom: 0, paddingRight: 8, width: 0, height: 0)
captionLabel.heightAnchor.constraint(greaterThanOrEqualToConstant: 0).isActive = true
// Green UILabel
addSubview(dateLabel)
dateLabel.anchor(top: nil, left: leadingAnchor, bottom: bottomAnchor, right: trailingAnchor, paddingTop: 0, paddingLeft: 8, paddingBottom: 0, paddingRight: 8, width: 0, height: 0)
What am I doing wrong here?
Actually, removing bottomAnchor from green box make it work:
And the code for this looks like:
// Yellow UILabel
addSubview(captionLabel)
captionLabel.anchor(top: actionButtonsStackView.bottomAnchor, left: leadingAnchor, bottom: nil, right: trailingAnchor, paddingTop: 0, paddingLeft: 8, paddingBottom: 0, paddingRight: 8, width: 0, height: 0)
captionLabel.heightAnchor.constraint(greaterThanOrEqualToConstant: 0).isActive = true
// Green UILabel
addSubview(dateLabel)
dateLabel.anchor(top: captionLabel.bottomAnchor, left: leadingAnchor, bottom: nil, right: trailingAnchor, paddingTop: 0, paddingLeft: 8, paddingBottom: 0, paddingRight: 8, width: 0, height: 0)
But why is it working? I thought by setting greaterThenOrEqual constant, the yellow UILabel auto size itself to just enough size to contain its contents, and the green UILabel adjust its size accordingly to bottomAnchor's yellow UILabel.
Upvotes: 0
Views: 708
Reputation: 11
That because you're adding two labels which have same priority of vertical content hugging (low
by default). If you want the the green label get higher, you can set the Content Hugging Priority
value of the red one to high
or required
. Here the code:
// Yellow UILabel
addSubview(captionLabel)
captionLabel.setContentHuggingPriority(.defaultHigh, for: .vertical)
captionLabel.anchor(top: actionButtonsStackView.bottomAnchor, left: leadingAnchor, bottom: nil, right: trailingAnchor, paddingTop: 0, paddingLeft: 8, paddingBottom: 0, paddingRight: 8, width: 0, height: 0)
// Green UILabel
addSubview(dateLabel)
dateLabel.anchor(top: captionLabel.bottomAnchor, left: leadingAnchor, bottom: bottomAnchor, right: trailingAnchor, paddingTop: 0, paddingLeft: 8, paddingBottom: 0, paddingRight: 8, width: 0, height: 0)
For more details you can this article: https://medium.com/@abhimuralidharan/ios-content-hugging-and-content-compression-resistance-priorities-476fb5828ef
Upvotes: 1