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

3

20

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
    }
Highgrade answered 27/11, 2019 at 6:22 Comment(3)
How much is the spacing that you've provided for this stack view? Try decreasing it. And you don't need a stack view for adjusting two labels. Autolayout can help you out with this kind of implementation.Massachusetts
Can you show us your desired state ?Mercurous
I edited my question @MojtabaHosseiniPrincipally
M
35

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.

Mencher answered 2/12, 2019 at 14:6 Comment(0)
M
2

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.

Mercurous answered 27/11, 2019 at 7:29 Comment(2)
Sorry I can't open Imgur, can you please write me the values?Principally
No problem, I have updated the answer with values. Note that my colors doesn't match with your colors.Mercurous
D
0

First embed your multiline label inside a view and constraint the label to this view (top, leading, trailing, bottom). After that add your view with your multiline label and single line label to your stackView.

Then you can use .fillProportionally for the distribution of your UIStackView and the spacing value to specify the space between your two labels.

Make also sure to use Required (1000) for your horizontal content compression resistance priority on your right number label.

View-hierarchy:

enter image description here

Result:

enter image description here

enter image description here

With spacing between your labels:

enter image description here

Doloresdolorimetry answered 27/11, 2019 at 6:26 Comment(5)
If I use fillEqually, firstLabel will be half of the width which is happening right now and I don't want it because second label can be so short the there can be enough space for first labelPrincipally
When I do fillProportionally, first label disappear.Principally
In my answer you are still using UIStackView to perform the auto layout part. You are just embedding the multiline label inside your stackview inside another view.Doloresdolorimetry
When I do it like that, second label lost Its priority which means that It showed like "113123342..." when It doesn't fit.Principally
Just use Required (1000) for your horizontal content compression resistance priority on your number label and you will be findeDoloresdolorimetry

© 2022 - 2024 — McMap. All rights reserved.