Search code examples
uilabelios6autolayout

How can I use Autolayout to create a layout that expands in height based on the content of a UILabel


I am attempting to build a dynamic layout using the new autolayout api in iOS 6.0. The layout that I am attempting to build has 2 buttons with a label inbetween them as shown in the image below:

enter image description here

What I would like is for the container view shown in grey to increase or decrease in size depending on the amount of text in the label.

So far I've managed to get the layout to work exactly as described with one small issue that I've not been able to resolve. The problem I am having is that the intrinsic height of the label is alway calculated with the original width of the label (e.g. the one set in interface builder) and not the width of the label that is set from the constraints I have on it.

The constraints that I have on the views are as follows:

  • H:|-[leftButton]-[label]-[rightButton]-|
  • Both buttons are centered Vertically
  • V: |-[label]-|
  • the content hugging priority of the buttons is higher than the label
  • the compression Resistance of the label is higher than the container view

All of these constraints together create the desired layout.

However:

  • If the Width of the label in interface builder (the literal size in interface builder) is less than the width of the view at runtime, then the height of the container is too large.

enter image description here

To help clarify this, the IB view of the above layout was as follows (note much narrower)

enter image description here

  • If the Width of the label in interface builder (the literal size in interface builder) is greater than the width of the view at runtime, then the height of the container is too small and lines of text get cut off.

What appears to be happening is that although there is no constraint on the labels width, the label seems to calculate its height (and thus the autolayout calculated height of the container) based on the original width of the label when it was created. However whats so strange is that the text appears to be the correct width and height but the label itself has a frame thats just too big or small.

I guess this is related to the order in which things are happening, and have tried calling updateConstraintsIfNeeded in the containerViews layoutSubview method however this doesn't appear to do anything.

Any suggestions would be greatly appreciated.


Solution

  • May be I am late but any way I've found solution. Any time when label width is changed you need to manually update preferredMaxLayoutWidth for Label. For example:

    Label.preferredMaxLayoutWidth = 200;
    

    Interface builder sets preferredMaxLayoutWidth with initial label width. Hope this helps.