I\'ve got a view that contains only a UILabel. This label contains multiline text. The parent has a variable width that can be resized with a pan gesture. My problem is t
Okay, I finally nailed it. The solution is to set the preferredMaxLayoutWidth in viewDidLayoutSubviews, but only after the first round of layout. You can arrange this simply by dispatching asynchronously back onto the main thread. So:
- (void)viewDidLayoutSubviews {
dispatch_async(dispatch_get_main_queue(), ^{
self.theLabel.preferredMaxLayoutWidth = self.theLabel.bounds.size.width;
});
}
That way, you don't set preferredMaxLayoutWidth until after the label's width has been properly set by its superview-related constraints.
Working example project here:
https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/ch23p673selfSizingLabel4/p565p579selfSizingLabel/ViewController.m
EDIT: Another approach! Subclass UILabel and override layoutSubviews:
- (void) layoutSubviews {
[super layoutSubviews];
self.preferredMaxLayoutWidth = self.bounds.size.width;
}
The result is a self-sizing label - it automatically changes its height to accommodate its contents no matter how its width changes (assuming its width is changed by constraints / layout).