Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Horizontal UIStackView with two label (one multiline label, one one-line)

I have a horizontal UIStackView which has two UILabel in it. First UILabel is multiline (two line) and other one is one line only. They both have default content compression and resistance priorities. My problem is that even there is a gap between labels, "best" word in first text goes second line. I noticed that first label doesn't goes beyond half of total width.

What I want is that second label should always show itself and first label should size It self for remaining space. If It can't fit to one line It should be two line. However, If second label is too short and first label is a long one but both of them can fit, first label should go beyond half of the width.

P.S I need to use UIStackView in this scenario because there are other cases. I know putting two label inside UIView may solve the problem.

UIStackView:
   - Distribution: Horizontal
   - Alignment: Center
   - Spacing: 0
   UILabel:
     - Number of line: 2
     - Line break: Word wrap
   UILabel:
     - Number of line: 1

Screenshot

View hierarchy:

enter image description here

Desired Result:

enter image description here

OR

enter image description here

EDIT: I calculate the width of second label and give width constraint. I think It solved my problem, I'll test a bit.

        //Give specific width to second label to make first one calculate right number of lines.
    if let font = UIFont(name: "Metropolis-ExtraBold", size: 15) {
        let fontAttributes = [NSAttributedString.Key.font: font]
        let size = (secondLabelText as NSString).size(withAttributes: fontAttributes)
        secondLabel.widthAnchor.constraint(equalToConstant: size.width).isActive = true
    }
like image 706
Emre Önder Avatar asked Nov 27 '19 06:11

Emre Önder


2 Answers

You should set different horizontal content compression resistants for each of them:

Multiple values

For this case, the blue one(multiline) should have something less than the orange one(Singleline).

Assistive note: Multiline: 250, Singleline: 750

Orange Settings: Orange Settings

Blue Settings: OrangeSettings

Note that I have set the line limit of the orange one to 0. You can set it to anything you like. But if you like to make it selfsize to anyhight taller view should have higher vertical compression resistant than 250.

like image 103
Mojtaba Hosseini Avatar answered Oct 15 '22 02:10

Mojtaba Hosseini


To try and simplify...

Forget calculating any widths... what matters is the horizontal Content Hugging and Content Compression Resistance

Leave the left (blue) label at the defaults:

Content Hugging Priority
    Horizontal: 251

Content Compression Resistance Priority:
    Horizontal: 750

But set the right (orange) label to:

Content Hugging Priority
    Horizontal: 1000

Content Compression Resistance Priority:
    Horizontal: 1000

Results:

enter image description here

The only other issue would be if the text in the right-side label exceeds the full width of the view -- but you haven't indicated that you might need that much text.

like image 38
DonMag Avatar answered Oct 15 '22 04:10

DonMag