ベン・ギルド (Ben Guild)


Fixing AutoLayout on UILabel(s) in iOS development

AutoLayout is a quick way to create largely responsive layouts on iOS 6 and above. However, I found that there's a really stupid problem with UILabel(s) in getting them to act like actual paragraphs that resize themselves to their own contents.

Oddly enough, calling “[label sizeToFit]” manually can band-aid the issue, but then hose the rest of your AutoLayout in some instances!

So what's wrong? Isn't AutoLayout supposed to automatically “compress” UILabel(s) to their minimum required size, based on their assigned constraints?

iOS AutoLayout UILabel Bug demonstrated (graphically)
As you can see, without this fix… the pink-colored label is taller in the same context when the view is loaded on a larger screen. 👎🏻

The tricky thing about UILabel(s) is that they don't always size themselves predictably due to a bug in UIKit. On iPad, you might end up with taller labels by default… where as on a 3.5-inch iPhone, they might look just fine.

The easiest resolution for this behavior is to subclass UILabel and add this little gem to force the “preferredMaxLayoutWidth” property of the label to reset automatically whenever the view is resized:

- (void)layoutSubviews {
    self.preferredMaxLayoutWidth = self.bounds.size.width;
    [super layoutSubviews];
}

This essentially ties its preferred text-rendering width to be the exact same as the view's width, as it most likely should be anyway, and leaves only its height to be adjusted dynamically by whatever the UILabel's content and AutoLayout constraints actually should be negotiating amongst themselves. 👍🏻

This approach not only keeps your code clean, but also keeps the issue isolated. However, it does require subclassing UILabel… which would be nicer if avoidable. 😕