4

I'm trying to align two UILabel's using Auto Layout, where the first label has no set width but using intrinsic content size and the second should be the same width as the first, wrapping text to new lines.

Ideally the second label should have number lines set to 0 to work with Dynamic Type, but I've set it to 2 for the time being and even given it a specific height. Yet when I try to align either equal widths or trailing, the intrinsic content size label expands to the width of the multiline label as if it was all on one line (see below illustration).

What I'm after: The effect I'm after

What I'm seeing: The effect I'm getting

Is there any way for me to achieve what I want without specifying a width for the first label? I'd like it to expand with the content to account for dynamic type, and for the second label to have the same width and wrap all text to a new line.

Aleksander
  • 2,735
  • 5
  • 34
  • 57
  • Can you provide more info about the first label, like maximum how many words it may contain? Can its content go past 1 line? Will it always have some text or it may also be empty? – Adeel Miraj Oct 16 '17 at 04:53
  • This might seem like a daft question but are you setting the first label equal to the width of the second or vice versa? – Jonathan Oct 16 '17 at 11:40
  • @Adeel the first label will only contain three words, but the reason why I want it to be dynamic is that I would like to add Dynamic Type and localize into multiple languages which may change that. It will never go past 1 line and it cannot be empty. – Aleksander Oct 16 '17 at 22:33
  • @Jonathan I'm setting the second label's width equal to the first (I've also tried to constrain the second label's trailing endpoint to the first), however it still seems to extend the first label's frame to that of the second as if all the text was on one line. This is probably because I'm never giving the first label a specific width, which causes it to extend to match the second. – Aleksander Oct 16 '17 at 22:35

2 Answers2

6

You can do it without hooking anything to the code. The key point of this solution is the content hugging priority for the label which size will be calculated based entirely on the intrinsic content size.

Intrinsic content size label

  • Set the horizontal content hugging priority to required (1000)

Multiline label (lorem ipsum label)

  • Align leading to Intrinsic content size label
  • Align trailing to Intrinsic content size label


Xcode configurations for both labels (left: Intrinsic, right: Multilabel)

configuration of intrinsic content size label configuration of multiline label

Kamil Szostakowski
  • 2,153
  • 13
  • 19
  • Thank you! I knew the content hugging/ compression numbers could have something to do with it, but they've always confused me and I was not able to trial-and-error myself to a solution. This works as a charm! – Aleksander Oct 18 '17 at 23:49
0

In layoutSubviews, set preferredMaxLayoutWidth of second label to first label intrinsic width, something like that:

secondLabel.preferredmaxlayoutwidth = firstLabel.intrinsicContentSize.width
Puneet Sharma
  • 9,369
  • 1
  • 27
  • 33
  • Is there a way to achieve this in Storyboard/ what should I do in storyboard so that it doesn't complain about unsatisfiable constraints? – Aleksander Oct 16 '17 at 03:11
  • Why is your storyboard complaining about unsatisfiable constraints? Please post screenshot of the error. – Puneet Sharma Oct 16 '17 at 03:26
  • Sorry, lack of better words. I just don't know what to set it to. If I don't give it the second label any width-based constraints, it spills out past the screen (as in illustration #2 above). I'd prefer the storyboard to be an accurate representation of what it'll actually render as. Is there any constraints I can set in the storyboard to achieve this, and help keep layout code away from my VC? – Aleksander Oct 16 '17 at 03:37
  • You dont have to delete your trailing constraints or equal widths constraint on storyboard. My answer does not mean your second label does not require those constraints. You can even specify preferredmaxlayoutwiddth in storyboard but its a constant value there, which I suppose is of not much for you as your first label is dynamic. You can try one more thing, give a trailing constraint to your second label to superview as well and make it greater than 10 or somethng. – Puneet Sharma Oct 16 '17 at 03:43
  • @Aleksander: Although I guess giving preferredmaxlayoutwidth in your view subclass is the best way to acheive what you are trying to acheive. – Puneet Sharma Oct 16 '17 at 03:49
  • 1
    This certainly works to achieve what I'm after, but I'm still hesitant to settle on this solution. Right now neither of these label are hooked up to my view controller, and I'd prefer to keep it that way if possible. I'll hold off on accepting your answer while I'm looking for alternative solutions, but will be sure to do so if I end up using it. If not I'll share the solution I did end up using with you. – Aleksander Oct 16 '17 at 22:39