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) } }}