iOS UITableView 刷新抖动解决及原因

原因:

目前比较优雅的实现tableViewCell高度自适应的方式一般是 为cell中的子控件设置相对于cell contentView的约束, 将cell撑开, 并不必去设置代理中的cell高度, 或者是将高度设置为 UITableViewAutomaticDimension(默认就是)

  • 正常逻辑过程: cell中的子项将cell撑开 -> tableView得到撑开后的cell高度->tableView设置cell高度
出现刷新抖动的逻辑大致是:
  1. tableView设置cell高度-> cell中的子项将cell撑开 -> tableView得到撑开后的cell高度(但并未设置)

导致的结果就是: 在ios11以下系统中, cell高度始终是44, ios11以上的系统会出现cell刷新抖动

先执行:

- (CGFloat)tableView:(UITableView *)tableView
 heightForHeaderInSection:(NSInteger)section;

后执行:
(此时cell并未创建和布局, cell高度是靠内容撑开,获取不到正确的高度 默认为44)

- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath;
  1. 解决->将执行顺序调整(为tableview的cell 设置预设高度)
    先执行
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath;

通过布局cell, cell被正确撑开 有正确的高度
后执行

- (CGFloat)tableView:(UITableView *)tableView 
heightForHeaderInSection:(NSInteger)section;

总结解决办法:

在使用约束实现cell高度自适应的时候, 为tableView cell预设高度改变TableView代理的执行顺序
self.tableView.estimatedRowHeight = **

headerView 和 footerView同理 对应的方法:
self.tableView. estimatedSectionHeaderHeight =**
self.tableView. estimatedSectionFooterHeight =**

不同版本区别: ios 11 之后系统预估高度有默认值 所以不给也是可以的

  1. 在ios 11 以下的系统中,只要有预估高度都是可以的,
  2. 但是ios 11之后,预估高度的设置要靠近最大cell高度实际值, 如果设置的预估高度的值比较小那么在刷新cell 的时候, 依然会出现抖动的问题

cell 中存在文本输入框

设置不正确 会出现cell在换行的时候 整个tableView抖动

  1. 首先要设置预估高度
    estimatedSectionHeaderHeight 设置为0 其他值依然会抖动
    estimatedSectionFooterHeight 设置为0 其他值依然会抖动
    estimatedRowHeight 设置合理即可

  2. Cell中如果存在高度差异太大的Cell
    建议不设置成自适应Cell 将他转成 headerView 或者 footerView
    这样在输入或者上下拉的时候 才能更顺畅,刷新也不会有抖动

小技巧

iOS UITableView 当contentSize.height < frame.height 的时候不滚动 反之滚动

  self.tableView.alwaysBounceVertical = NO;
  self.tableView.bounces = YES;

你可能感兴趣的:(iOS UITableView 刷新抖动解决及原因)