When I use Auto Layout to choose each cell's height (so they're dynamic) it mostly works, but some cells are a little short. Why is this?

Example project: http://cl.ly/2j0A1J203f3h

I’m trying to use Auto Layout to dynamically determine each cell’s height so some cell’s can hold more content than others. To do this I’m using this Stackoverflow answer and the accompanying GitHub example.

  • userInterfaceIdiom always indicate iPhone
  • Best way to enum NSString
  • iOS Facebook Graph API Profile picture link
  • How to record a video with avfoundation in Swift?
  • Bug in UITableView ( deleteSections:withRowAnimation: )?
  • Detecting whether or not device support phone calls?
  • I have a UITableViewCell subclass called CSPostCell that I created in the Storyboard and put a UILabel in with a maximum of 5 lines of text in the label.

    Just for example purposes, I’m only having two cells in the table and as such two different pieces of text for the labels (one’s longer) which is set up in cellForRowAtIndexPath::

    - (CSPostCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        CSPostCell *cell = [tableView dequeueReusableCellWithIdentifier:@"SelfPostCell" forIndexPath:indexPath];
        cell.postTitle.text = indexPath.row == 0 ? @"Short title" : @"Long long long title. Holy crap this is one long title. When does it end? Oh right now.";
        [cell setNeedsUpdateConstraints];
    
        return cell;
    }
    

    I then return the height of each cell as such:

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
        CSPostCell *cell = [tableView dequeueReusableCellWithIdentifier:@"SelfPostCell"];
    
        cell.postTitle.text = indexPath.row == 0 ? @"Short title" : @"Long long long title. Holy crap this is one long title. When does it end? Oh right now.";
        cell.postTitle.preferredMaxLayoutWidth = tableView.bounds.size.width - 40;
    
        [cell setNeedsUpdateConstraints];
        [cell updateConstraintsIfNeeded];
        [cell.contentView setNeedsLayout];
        [cell.contentView layoutIfNeeded];
    
        CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
    
        return height;
    }
    

    Which is more or less an exact copy from the GitHub repo example.

    However, when I run the app in the simulator, it doesn’t quite work as it should. The heights are dynamic and adjust for longer pieces of text, but not enough that the text doesn’t get cut off. See the image below:

    enter image description here

    In that above case the second cell’s label should show another line to finish off the text, but it gets cut off.

    Why is it not showing all the text?

    Solutions Collect From Internet About “When I use Auto Layout to choose each cell's height (so they're dynamic) it mostly works, but some cells are a little short. Why is this?”

    This simplified code worked well for me, with just one slight fudge of 2 points. All the calls to updateConstraints seem to be unnecessary. I’m not sure why you need the fudge factor — maybe some padding in the label? I tested it with different length strings and different font sizes, and it always worked correctly.

    - (CSPostCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        CSPostCell *cell = [tableView dequeueReusableCellWithIdentifier:@"SelfPostCell" forIndexPath:indexPath];
        cell.postTitle.text = indexPath.row == 0 ? @"Short title" : @"Long long long title. Holy crap this is one long title. When does it end? Oh right now.";
        return cell;
    }
    
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
        CSPostCell *cell = [tableView dequeueReusableCellWithIdentifier:@"SelfPostCell"];
        cell.postTitle.text = indexPath.row == 0 ? @"Short title" : @"Long long long title. Holy crap this is one long title. When does it end? Oh right now.";
        cell.postTitle.preferredMaxLayoutWidth = tableView.bounds.size.width - 40;
        CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
        return height + 2;
    }