iOS tableviewcell自适应高度的笔记

作者: 突刺刺 | 来源:发表于2021-02-10 20:48 被阅读0次

中心点

iOS8后面,其实啥也不用干。最核心的做了下面两点,就能达到cell自适应高度:
  • 需要添加cell的子视图的约束top, bottom,left,right
  • 不要实现UITableViewDelegate中,任何返回cell高度的代理方法:
    • - (CGFloat)tableView:(UITableView *)tableView    heightForRowAtIndexPath:(NSIndexPath *)indexPath;
      
    • - (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath;
      

先说总结出的三种可行方式

  • 代码写布局控件:
    • cell要自定义
    • 满足上面两个核心条件
    • tableView.estimatedRowHeight的预估值,可以让cell复用率提高,节省内存。
  • xib写布局:
    • xib创建一个cell(本身就是自定义了一个cell)
    • 满足上面两个核心条件
    • 一直创建新的cell,如果数据非常非常多,要考虑内存问题
  • 如果cell里面只装载文字,直接用系统UITableViewCell自带的text label,cell复用率最高。 但使用场景低。

问题

光是实现上面两个核心要件,也不能任意场景下,完美实现cell自适应高度,还有一些事情是需要厘清的。
  • tableView.rowHeight = UITableViewAutomaticDimensiontableView.estimatedRowHeight = 10,起了什么作用。
  • 纯代码使用系统UITableViewCell,创建一个label,添加到系统UITableViewCell,最后导致所有cell 高度一致
  • 纯代码使用系统UITableViewCell,并使用系统UITableViewCell自有的textlabel,复用率最高,而且高度不复用,效果完美
  • 纯代码使用 自定义cell,能够避免cell的高度复用,原因是不是cell没有复用
  • xib使用自定义cell,也能最简单没有坑的实现cell高度自适应,并且避免了高度一致,原因是不是也是cell没有复用?
  • 使用masnory原生NSLayoutConstraint,结果有什么区别?

探索

1. 设不设置tableView.rowHeight = UITableViewAutomaticDimension,有什么影响?
  • 点开系统UITableView.h,可以看到
    @property (nonatomic) CGFloat rowHeight;             // default is UITableViewAutomaticDimension
    
    系统默认的就是UITableViewAutomaticDimension
2. 设不设置tableView.estimatedRowHeight = xxx.0f,有什么影响?
  • 其实这个值设置多少,影响还是有的。用下面个例子证实:
    • 一个array 包含12个字符串,用label显示。
    • 设置label.numberOfLines=0
    • 纯代码自定义的cell中添加label,并且添加label上下左右约束。
    • 在下面方法中断点
      if (!cell)
      {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellid];
      }
      
    • tableView.estimatedRowHeight = 任意值
  • 可以看到,随着tableView.estimatedRowHeight值的变化,上面断点的次数也会不一样,最多会有13次的断点。最少会有当前屏幕cell个数+1的次的断点。这说明了,cell复用次数,居然不一定了?那就只能一个原因:
    • tableView.estimatedRowHeight的值,可以让label把所有字符串显示出来,系统就会到cell复用池去寻找符合这个高度的cell。如果有,就复用,如果没有就重新创建。
    • 当设置tableView.estimatedRowHeight = 1时,明显这个高度不能让任何label完全显示,这个时候,就会发现,上面断点走了13次,而整个array只有12字符串元素。这就说明cell没有任何复用!
3.用纯代码创建一个label,添加在 系统UITableViewCell中,并添加上下左右约束,高度复用
  • 同样在cell==nil的条件中打上断点,发现断点次数永远是当前屏幕显示的cell的个数+1,同时滚动几次,12个cell高度一样,这说明了,使用系统UITableViewCell,cell复用率最高,但是高度最后也会一样,这样的效果,现实项目中根本不能用。
4.使用系统UITableViewCell中的自有的textlabel装载array的元素字符串,并设置textlabel.numberOfLines=0cell复用率最高,且高度不会复用,效果完美。
  • 这种效果从内存优化角度,和高度自适应角度,效果是最好的。可是系统UITableViewCell自带的textlabel,使用场景很低很低,稍微复杂的项目,就不能用。
  • 可是为什么自定义一个label,就会高度复用?没搞明白。
5.用纯代码创建一个label,添加在自定义Mycell中,并添加上下左右约束,效果完美,但是有没有复用?
  • tableView.estimatedRowHeight=0时候,发现断点次数永远是array.count+1次,
  • tableView.estimatedRowHeight的值能够让某个lable完全显示字符串,断点次数就比array.count+1少了。
  • 结论:明显这个没有复用。之所以有时候复用,完全是tableView.estimatedRowHeight的值设置恰当。
6. 用xib创建一个cell,拉好控件label,拉好上下左右约束,原因是不是也是cell没有复用?
  • 这种方式一直滚动,一直断点,跟tableView.estimatedRowHeight的值没有关系。
  • 结论:xib自定义cell,会一直创建新的cell。因此高度永远不会一致。
7.用masonry原生NSLayoutConstraint,有什么区别?
  • 没有任何区别,需要注意的是,masnory内部设置了label.translatesAutoresizingMaskIntoConstraints = NO。用原生NSLayoutConstraint,要加上一句label.translatesAutoresizingMaskIntoConstraints = NO

结论

  • tableView.rowHeight = UITableViewAutomaticDimension设不设置,毫无影响。
  • 纯代码下:
    • 自定义tableViewcell装载字符串,tableView.estimatedRowHeight的值,会决定cell复用的次数。
    • 系统UITableViewCell中添加自定义label装载字符串,tableView.estimatedRowHeight的值,会决定cell复用的次数,而且cell的高度也会复用,一直滚动,最后所有cell高度一致。这个方式几乎可以抛弃。
  • 使用系统UITableViewCell又分两种情况:
    • 一种使用系统UITableViewCell自带的textlabel,效果好,使用场景低。几乎用不到。
    • 一种自定义label添加到系统UITableViewCell上,高度也会复用。这个方式几乎可以抛弃
    • 系统UITableViewCell自带的textlabel既然能无bug实现,自定义label肯定也能完美实现,只是还没找到原因。
  • xib创建一个自定义tableViewcell,会一直创建新的cell。结果高度肯定也不会复用。
  • 使用原生NSLayoutConstraint添加约束时,注意设置label.translatesAutoresizingMaskIntoConstraints = NO

相关文章

网友评论

    本文标题:iOS tableviewcell自适应高度的笔记

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