UITableView自适应cell高度

2017-12-25  本文已影响0人  多来猫

虽然早就知道如何在UITableView中自适应cell的高度,但接手公司项目比较老旧,一直都是手动计算cell高度的,所以也只能写个demo验证一下,还没有在项目中实战。直到前几天有个复杂页面崩溃的问题,我一狠心花了几天时间重构了一下。现记录一下遇到的坑:

手动计算高度

在手动计算cell高度的年代,我们的代码大概是这个样子的

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    MyModel *model = [self.modelList objectAtIndex:indexPath.row];
    return [MyCell heightForModel:model];
}

这样计算出来的高度再做缓存,下次直接取出即可。如果是固定高度也可以写成这样

self.tableView.rowHeight = 44;

但这样的问题就是计算起来太麻烦

使用autolayout计算cell高度

使用autolayout计算cell高度的思路很简单
1、估算cell高度
2、使用autolayout填充cell,保证cell的contentView上下被子视图撑开

self.tableView.estimatedRowHeight = 55;
self.tableView.rowHeight = UITableViewAutomaticDimension;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"identify" forIndexPath:indexPath];
    [cell.contentView addSubview:self.tipLabel];

    //设置top和bottom的margin,再加上label自适应的高度就可以计算出contentview的高度了
    [self.tipLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.mas_equalTo(15);
        make.right.mas_lessThanOrEqualTo(-15);
        make.top.mas_equalTo(15); //设置顶部margin为15
        make.bottom.mas_equalTo(-15); //设置底部margin为15
    }];
}

如果cell高度是可变的,可以通过以下代理方法来设置cell的估算高度

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 0) {
        return 44;
    }
    else {
        return 88;
    }
}

使用autolayout计算section header、footer高度

使用autolayout计算section header、footer高度的思路与计算cell高度类似
1、估算header、footer的高度
2、使用子视图撑开header、footer

self.tableView.estimatedSectionHeaderHeight = 10.0;
self.tableView.estimatedSectionFooterHeight = 1.1;
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    UITableViewHeaderFooterView *headerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:@"identifier"];
    [headerView.contentView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.mas_equalTo(0);
        make.height.mas_equalTo(10.0);
    }];
    return headerView;
}

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
    UITableViewHeaderFooterView *footerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:@"identifier"];
    [footerView.contentView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.mas_equalTo(0);
        make.height.mas_equalTo(10.0);
    }];
    return footerView;
}

如果section的header、footer的高度是可变的,可以通过实现以下代理方法来设置section的header、footer估算高度

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForFooterInSection:(NSInteger)section
{
    if (section == 0) {
        return 10;
    }
    else {
        return 20;
    }
}

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForHeaderInSection:(NSInteger)section
{
    if (section == 0) {
        return 10;
    }
    else {
        return 20;
    }
}

使用autolayout计算tableHeaderView、tableFooterView的高度

tableHeaderView、tableFooterView还没完全支持autolayout,如果使用autolayout对tableHeaderView、tableFooterView进行布局还需要手动计算frame😓

遇到的坑

1、使用估算高度的时候,与实际高度不能相差太大。否则tableView会闪烁蹦跳
2、估算高度必须大于1,否则在iOS10及以下版本会崩溃
3、UIImageView的高度需要手动制定,否则图片太大的时候不会压缩UIImageView的高度

上一篇下一篇

猜你喜欢

热点阅读