美文网首页
UITableView自动(手动)混合计算高度

UITableView自动(手动)混合计算高度

作者: perfect_coding | 来源:发表于2020-02-17 13:14 被阅读0次

    1、属性介绍

    在 iOS7.0之后出现了estimatedRowHeight这个属性,
    @property (nonatomic) CGFloat estimatedRowHeight NS_AVAILABLE_IOS(7_0); // default is UITableViewAutomaticDimension, set to 0 to disable
    当我们在cell里面添加完所需控件,并约束好位置之后,我们只需要设置

    // self-sizing技术 (iOS8 开始支持的),iOS8之后默认就是这个值,可以省略
    // 告诉tableView所有cell的真实高度是自动计算的(根据设置的约束自动计算)
    self.tableView.rowHeight = UITableViewAutomaticDimension;
    // 告诉tableView所有cell的估算高度
    self.tableView.estimatedRowHeight = 44;
    

    就可以由系统自动计算高度。
    那怎么样才算约束好呢?才能保证系统准确的计算出我们想要的高度呢?

    2、子view布局要求

    cell的布局核心:
    cell的contentView的子视图支持起contentView,即每个子视图上下左右都要有约束,最后一个视图的bottom要设置的和contentView的bottom一样。这样宽高都有了,就可以自动进行约束了

         [self.contentView addSubview:_contentLabel];
         [self.contentView addSubview:_headerImage];
            // 约束可以直接放在创建的地方
            // 不要放在layoutSubviews 或 updateConstraints方法里
            [_headerImage mas_makeConstraints:^(MASConstraintMaker *make) {
                make.left.equalTo(self.contentView).offset(10);
                make.top.equalTo(self.contentView).offset(20);
                make.height.width.equalTo(@50);
            }];
            
            [_contentLabel mas_updateConstraints:^(MASConstraintMaker *make) {
                make.top.equalTo(_headerImage.mas_bottom).offset(5);
                make.left.right.equalTo(self.contentView);
                // 这一步是关键 让cell知道最底部在哪儿, 然后算出自身高度
                make.bottom.equalTo(self.contentView);
            }];
    

    参考布局博文
    UITableViewCell高度自适应 使用Masonry纯代码约束

    3、进一步理解自动计算高度

    我想在大家初次解决tableViewCell高度自适应问题的时候应该会这样想过:在绘制cell的时候我们可以得到cell准确的高度,如果拿到这个高度设置成cell的高度不是刚刚好吗? 悲剧的是tableView显示数据的时候会先调用高度的协议方法(heightForRow...),然后才进行绘制(调用cellForRow...),也就是说,调用高度的时候cell可能都还不存在呢!

    tableView: estimatedHeightForRowAtIndexPath:就是为了改变这个问题诞生的.我们用数据说话:当我们没有调用estimatedHeightForRow...这个方法的时候,tableView调用几个代理方法的顺序是这样的:(测试数据为5行)

    image.png

    可以看出,控制器在得知cell的行数n之后,会先一口气调用n次heightForRow方法,这是为了方便tableView计算自己的contentSize,进一步计算指示条的大小和位置.

    在添加了estimatedHeightForRow...方法后,调用顺序变成了:

    image

    也就是说,愿望实现了. 这个方法的出现使得tableView代理方法的调用顺序发生了改变,从而达到了前面说的"绘制cell时得到准确高度,然后把高度再拿给tableView去显示"的目的.并且,这个方法避免了一开始调用n次heightForRow的方法导致的一些不必要的计算.

    4、关于性能方面

    可以参考博文[5]
    其实在官方文档中已经有详细的介绍:


    image.png

    利用预估的高度,可以提升tableView的加载数据的性能。

    那如果我们想要一部分cell需要手动计算高度,而另一部分cell需要自动计算高度,又该如何处理呢?

    其实,关键在于以下核心代码:

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if (indexPath.section == 0 || indexPath.section == 1) {
                return 81;
        }
        // 注意:解决固定行高和系统自动计算行高  其他组走系统自动计算行高
        return UITableViewAutomaticDimension;
    }
    

    想用预估,直接返回UITableViewAutomaticDimension,否则返回计算的高度。追根溯源我们参考文档描述,如下:


    image.png

    参考博文:

    1. UITableViewCell高度自适应探索
    2. iOS UITableView 解决估算行高和指定行高的矛盾
    3. UITableView自动计算Cell高度思路
    4. UITableView高度问题
    5. iOS开发中行高灵活可变的UITableView的性能优化

    相关文章

      网友评论

          本文标题:UITableView自动(手动)混合计算高度

          本文链接:https://www.haomeiwen.com/subject/wmfbfhtx.html