Invalid size returned by systemLayoutSizeFittingSize when using a multi-line label

I have a custom MyCell table cell that has only 1 multi-line label with side restrictions. The xib size is 320 x 280 . enter image description here

I use systemLayoutSizeFittingSize to calculate cell height based on content:

 - (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { MyCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyCell"]; // set cell width = table width CGRect rect = cell.frame; rect.size.width = CGRectGetWidth(tableView.frame); cell .frame= rect; // update the text cell.mainLabel.text = @"Some multiline text. Some multiline text. Some multiline text. Some multiline text. Some multiline text. Some multiline text. Some multiline text. Some multiline text."; [cell setNeedsLayout]; [cell layoutIfNeeded]; CGSize size = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]; NSLog(@"size %@", NSStringFromCGSize(size)); // {290.5, 117.5} return size.height; } 

MyCell layoutSubviews as follows

 - (void) layoutSubviews { [super layoutSubviews]; NSLog(@"cell frame %@", NSStringFromCGRect(self.frame)); // {{0, 0}, {375, 280}} NSLog(@"self.mainLabel frame %@", NSStringFromCGRect(self.mainLabel.frame)); // {{8, 8}, {304, 264}} [self.mainLabel updatePreferredMaxLayoutWidth]; } 

updatePreferredMaxLayoutWidth is the category updated by preferredMaxLayoutWidth if the frame width does not match preferredMaxLayoutWidth

 -(void)updatePreferredMaxLayoutWidth { if (self.numberOfLines == 0) { if ( self.preferredMaxLayoutWidth != self.frame.size.width){ self.preferredMaxLayoutWidth = self.frame.size.width; [self setNeedsUpdateConstraints]; } } } 

Now, when I run, I get the output:

 cell frame {{0, 0}, {375, 280}} 

The cell size in layoutSubviews is the same width as the table view, right

 self.mainLabel frame {{8, 8}, {304, 264}} 

self.mainLabel frame inside layoutSubviews is 304, which is equal to the size of the label inside the xib file. Thus, the label frame was not updated to the new cell size. What for?

 size {290.5, 117.5} 

The size of systemLayoutSizeFittingSize , which is completely wrong. What did I miss?

+6
source share
2 answers

Call

 [self.contentView layoutIfNeeded]; 

in layoutSubviews cell, fixed the problem.

Source Table view items with varying row heights

+4
source

You can use this class to solve all problems with your UILabel and AutoLayout

 class UILabelPreferedWidth : UILabel { override var bounds: CGRect { didSet { if (bounds.size.width != oldValue.size.width) { self.setNeedsUpdateConstraints() } } } override func updateConstraints() { if(preferredMaxLayoutWidth != bounds.size.width) { preferredMaxLayoutWidth = bounds.size.width } super.updateConstraints() } } 
+1
source

All Articles