I have a custom MyCell table cell that has only 1 multi-line label with side restrictions. The xib size is 320 x 280 . 
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?