Autolayout adding extra padding on top and bottom of UILabel iPhone 6/6+ when preferredMaxLayoutWidth is set Autolayout adding extra padding on top and bottom of UILabel iPhone 6/6+ when preferredMaxLayoutWidth is set ios ios

Autolayout adding extra padding on top and bottom of UILabel iPhone 6/6+ when preferredMaxLayoutWidth is set


So what i ended up doing was to create a subclass for the label and override setBounds: and set the preferredMaxLayoutWidth to its bounds.

- (void)setBounds:(CGRect)bounds {    [super setBounds:bounds];    if (self.preferredMaxLayoutWidth != bounds.size.width) {        self.preferredMaxLayoutWidth = bounds.size.width;        [self setNeedsUpdateConstraints];}}

Also, in the UITableViewCell subclass, i override the layoutSubiews

- (void)layoutSubviews {    [super layoutSubviews];    [self.contentView layoutIfNeeded];    // labelsCollection is an IBOutletCollection of my UILabel sublasses    for (UILabel *label in self.labelsCollection) {        label.preferredMaxLayoutWidth = label.bounds.size.width;}}

This works all the time. I think the reason for this odd behavior is that the UILabel is initially set to 280px (320px - padding on either side) in the xib file but during run time, it changes its width to accommodate bigger screens (since I set the leading and trailing constraints it increases the width which changes the 'preferredMaxLayoutWidth' to a bigger value). For some reason UILabel doesn't update its preferredMaxLayoutWidth to the bigger value and causes the white space on top and bottom.

That's my hypothesis.

Hope this helps.


Anyone looking into this question that already is using maxPreferredLayoutWidth (btw you do not have to subclass, just set this in viewDidLayoutSubviews of your VC) check that you are setting it to the width of the correct view.

Mine was not working because I had:

label1.maxPreferredLayoutWidth = label1.frame.widthlabel2.maxPreferredLayoutWidth = label1.frame.width

When it should have been:

label1.maxPreferredLayoutWidth = label1.frame.widthlabel2.maxPreferredLayoutWidth = label2.frame.width

Do you see the difference? I did not for 3 hours lol


using this class fixed it for me

import UIKitclass CustomLabel: UILabel {    override func drawText(in rect: CGRect) {        if let stringText = text {            let stringTextAsNSString = stringText as NSString            let labelStringSize = stringTextAsNSString.boundingRect(with: CGSize(width: self.frame.width, height: CGFloat.greatestFiniteMagnitude), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil).size            super.drawText(in: CGRect(x: 0, y: 0, width: self.frame.width, height: ceil(labelStringSize.height)))        } else {            super.drawText(in: rect)        }    }}