Sean Danzeiser
Sean Danzeiser

Reputation: 9243

iOS 7 incorrect calculation of UITableViewCell height on first pass

I'm trying to calculate the height of my uitableviewcell subclass in iOS 7 and I am finding that, on first pass, the calculation is incorrect. However, if I reload the tableview a second later, the calculation is indeed correct on second pass. Here is how I am calculating the cell height:

    if (_prototypeHeader == nil) {
            _prototypeHeader = [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([DDStatusTableViewCell class]) owner:nil options:0] lastObject];
    }
    [_prototypeHeader setFrame:CGRectMake(0, 0, CGRectGetWidth(tableView.frame), 0)];
    [_prototypeHeader configureForMenu:self.menu atRestaurant:self.restaurant];
    [_prototypeHeader setNeedsLayout];
    [_prototypeHeader layoutIfNeeded];

    CGSize size = [_prototypeHeader.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
    NSLog(NSStringFromCGSize(size));
    return size.height + 1;

The log statement is logging this for the size:

2014-10-28 10:15:45.492 MyApp[39252:613] {350, 77} <--- this is incorrect
2014-10-28 10:15:46.495 MyApp[39252:613] {294, 110} <--- this is correct

I've also logged out the tableview width in both circumstances and it appears to be a consistent 320. This is only an issue in iOS 7. What gives?

Thanks!

EDIT

After further inspection, I've determined that the layout width of my top label is incorrect. Within the label's layoutSubviews method, I do this:

- (void)layoutSubviews {
    [super layoutSubviews];
    self.titleLabel.preferredMaxLayoutWidth = self.titleLabel.frame.size.width;
    self.detailLabel.preferredMaxLayoutWidth = self.detailLabel.frame.size.width;
    [super layoutSubviews];
}

In the first pass, the titleLabel's width is 170, while in the second pass, the width is 130. Still trying to figure out why. The contentView's width is also 360 during the first pass, and shrinks down to 320 for the second pass. It seems as though the layout code that adjusts the label's width occurs before the contentView has adjusted its size.

Upvotes: 3

Views: 671

Answers (1)

Sean Danzeiser
Sean Danzeiser

Reputation: 9243

asking the cell to layout the contentView before changing the preferredMaxLayoutWidth seems to do the trick.

- (void)layoutSubviews {
    [super layoutSubviews];
    [self.contentView layoutIfNeeded];
    self.titleLabel.preferredMaxLayoutWidth = self.titleLabel.frame.size.width;
    self.detailLabel.preferredMaxLayoutWidth = self.detailLabel.frame.size.width;
    [super layoutSubviews];
} 

Upvotes: 3

Related Questions