UITableViewCell的高度自适应

一、官方方法

1、实现为每个cell设置高度的协议方法。UITableViewAutomaticDimension的值为-1,告诉系统cell高度自适应。

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return UITableViewAutomaticDimension;
}

2、设置cell中字视图纵向的约束要确定好,将cell撑满。比如子视图中label,本身高度可以变化,但是label上、下边界与cell要确定好。使用xib的约束没有问题,但是使用Masonry实际中label约束不太一样。

[_stringLabel makeConstraints:^(MASConstraintMaker *make) {
    make.centerX.equalTo(self.contentView);
    make.width.equalTo([UIScreen mainScreen].bounds.size.width-40);
    make.top.equalTo(self.contentView).offset(10);
}];

这里写死宽度。

二、自定义

1、同上第2步

2、实现高度估算的协议方法,改变tableview协议方法加载顺序。

默认的顺序是 height >> cell,现在是 estimatedHeigh >> cell >> height。

-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath;

3、在cellForRowAtIndexPath方法中填充模型,并强制刷新cell。

// 强制刷新
[self setNeedsLayout];
[self layoutIfNeeded];

// 计算刷新后的高度,赋值给model,存起来
_model.cellHeight = CGRectGetMaxY(_stringLabel.frame)+8;

4、 在height方法中返回

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    Model *model = _array[indexPath.row];
    if (model) {
        return model.cellHeight;
    }
    return 44;
}

三、UITableViewHeaderFooterView高度自适应

虽然官方文档说,实现estimatedHeightForFooterInSection方法,会先执行viewForFooterInSection方法,但是我实际中发现并不是这样。执行的顺序仍然是 heightForFooterInSection >> viewForFooterInSection。

1、UITableViewHeaderFooterView中做好自适应约束。

2、在viewForFooterInSection方法中调用 [tableView beginUpdates];[tableView endUpdates];期间会再次调协议heightForFooterInSection方法。

3、代码:

//- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForFooterInSection:(NSInteger)section {
//    
//    return 60;
//}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
    
    TodayWeatherMiddleModel *model = _dataManager.dataArray[_currentIndex][2];
    if (model.footerHeight) {
        return model.footerHeight;
    }
    return 60;
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
    
    BETableViewHeaderFooterView *footerView = [BETableViewHeaderFooterView dequeueReusableViewWithTableView:tableView isHeaderView:NO];
    
    TodayWeatherMiddleModel *model = _dataManager.dataArray[_currentIndex][2];
    if ([model isKindOfClass:[TodayWeatherMiddleModel class]]) {
        
        footerView.middleModel = model;
        // 容易崩溃,强制tableview重新调用heightForFooterInSection方法。会创建多个footerview。
// 效果都不好,在willDisplayFooterView中强制刷新,虽然会浪费一些时间,但是会好很多。
        // [tableView beginUpdates];
        // [tableView endUpdates];
        [tableView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 0)] withRowAnimation:UITableViewRowAnimationNone];
    }
    
    return footerView;
}

- (void)tableView:(UITableView *)tableView willDisplayFooterView:(UIView *)view forSection:(NSInteger)section {
    
    [tableView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 0)] withRowAnimation:UITableViewRowAnimationNone];
    
}

四、手动先生成reuseview,给reuseview赋model,计算出高度,再返回高度。
1、view自适应
2、在heightFoXXX方法中创建reuseview, 赋值model填充reuseview内容,计算高度,并将高度返回给model。最后再返回高度。

总结:view自适应,原则是先计算高度(根据cell和model)并缓存,再返回view。
参考于stackoverflow

你可能感兴趣的:(UITableViewCell的高度自适应)