UITableViewCell dynamic height with AutoLayout conclusion


I've post Table View Cell Dynamic Height With AutoLayout for iOS 7 later last month, however been using this technique for a month since then, I found this the technique Table View Cell Dynamic Height With AutoLayout for iOS 7 later mentioned brings me laggy performance, because of cell trying to relayout twice when calculating heightForRowAtIndexPath: and preparing cellForRowAtIndexPath:. As you seen below.

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    static CommentedItemCell *sizingCell = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sizingCell = [self.tableView dequeueReusableCellWithIdentifier:kCellIdentifier];
    AnyItem *item;
    [sizingCell configureCell:item];
    [sizingCell setNeedsLayout];
    [sizingCell layoutIfNeeded];
    CGFloat height = [sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
    return height;

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    CommentedItemCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier forIndexPath:indexPath];
    AnyItem *item;
    [cell configureCell:item];
    return cell;

Performance problem is impact but not most frustrated, the technique depends on systemLayoutSizeFittingSize will calculate UITableViewCell size on Cell's layoutsubviews: method, I found out I always get {320, 44} at the first time, no matter which device I use, let alone the UIView-Encapsulated-Layout-Height issue. I know there's some ways to prevent it, but I'm so unsure about it, I don't feel happy when I solve the issue.

So, I keep looking for better solution to replace systemLayoutSizeFittingSize one.


Finally, that the subviews of cell calculate itself by intrinsicContentSize method, the old school technique works well for me, and I guess most of iOS programmer expericenced intrinsicContentSize method.

Create an UILabel subclass first.

Set constraints on your UITableViewCell well, you don't need to set Content Hugging and Content Compression Resistance anymore, because the UILabel calcutate it's height by self already. And you don't have to lower your constrints priority for UIView-Encapsulated-Layout-Height issue. Just set plain constraints for your cell.

And your UITableViewCell.m

- (void)layoutSubviews
    [super layoutSubviews];

    [self.label setNeedsLayout];
    [self.label layoutIfNeeded];

The controller which handles UITableViewDelegate do not implement heightForRowAtIndexPath method. Let the cell calculate the height and it will be set.

Most important thing is set estimatedRowHeight either by self.tableView.estimatedRowHeight or delegation estimatedHeightForRowAtIndexPath ways. This aid UITableView to knows how many cells it could appear at once time and relative to scrolling position.

That's it.

Please leave your comment about these two UITableViewCell dynamic height with AutoLayout techniques.

comments powered by Disqus