我们都知道自动iOS8开始,苹果新增Self-Sizing功能,虽然说大家都知道有坑,但是确实很方便。大家使用Masonry对UITableView的Cell进行约束布局(原生AutoLayout使用不方便)能够快速对Cell进行高度自适应,省去了许多手动计算高度的麻烦,然而高度或者内容改变后,也给我带来了一个大坑。
踩坑环境
UITableView自动评估高度有连两个关键步骤:
self.tableView.estimatedRowHeight = 100;
self.tableView.rowHeight = UITableViewAutomaticDimension;
当然以上的前提是你cell使用了AutoLayout或者第三方库Masonry进行布局约束,满足这些条件后,对于每一个Cell的高度,系统就能为了自动计算好。
踩坑条件
以上的东西看起来很简单,也确实简单,但是坑来了:
estimatedRowHeight 这个值我们一般都是随便给,很多文章给出的注释也是最好接近实际高度。然后很多不明所以的同学也是习惯给个40(我也是),确实在平常使用的时候没有太大的问题。
但是,当我们插入或者删除某个Cell,或者Cell的内容高度发生变化的时候,我们执行[tableView reloadData]的时候,或者执行完毕滑动的时候会发现 tableview的内容会出现闪动,漂移的情况
原因和解决办法
对于estimatedRowHeight上面也说过,我们经常会随便设置一个值,但其实这个值是十分重要的,尽量要接近实际的高度(如果是布局内容的高度相差不远的话),因为系统会根据这个值对内容进行多次评估,如果相差比较远的话就会多次调用。
对于上述tableview出现闪烁、漂移的情况,大部分的根本原因就是内容改变,系统根据你设定的预估值进行计算,重新设置偏移量(这里要说明的是,即使内容高度没有改变,每个Cell出现或者即将出现到屏幕的时候系统都会重新计算高度,只是高度不变化,对于tableview偏移量没有影响,我们就看不到闪烁)
那么我们要怎么解决这个问题呢:
-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath{
NSMutableArray *commentArray = self.dataArray[indexPath.section].commentArray;
CommentModel *model = commentArray[indexPath.row];
if (model.height == 0) {
return 40;
}else{
return model.height;
}
}
最直接的办法就是,我们自动布局完成以后,对高度进行一次缓存,下次重新评估cell的高度的时候,直接赋值给 预估值 这样,系统在评估内容高度的时候就能够快速的得到结果,避免多次计算带来的偏移量跳动。
并且这个有一个好处就是,可以降低,系统评估高度的次数,降低性能损耗。提高界面的流畅度。
如发现不当之处,请反馈!
网友评论