前几天给大家介绍了一个自适应cell高度的第三方开源扩展,今天我们试着不依靠第三方框架在使用Autolayout的基础上进行cell高度的自适应.
在进入正题之前,让我们先认识一个方法
tableView: estimatedHeightForRowAtIndexPath:
这是7.0出现的UITableViewDelegate中的方法,表示返回某行cell的预估高度.
那么这个预估高度有什么作用呢?
我想在大家初次解决tableViewCell高度自适应问题的时候应该会这样想过:在绘制cell的时候我们可以得到cell准确的高度,如果拿到这个高度设置成cell的高度不是刚刚好吗? 悲剧的是tableView显示数据的时候会先调用高度的协议方法(heightForRow...),然后才进行绘制(调用cellForRow...),也就是说,调用高度的时候cell可能都还不存在呢!
tableView: estimatedHeightForRowAtIndexPath:就是为了改变这个问题诞生的.我们用数据说话:当我们没有调用estimatedHeightForRow...这个方法的时候,tableView调用几个代理方法的顺序是这样的:(测试数据为5行)
之前的调用顺序
可以看出,控制器在得知cell的行数n之后,会先一口气调用n次heightForRow方法,这是为了方便tableView计算自己的contentSize,进一步计算指示条的大小和位置.
在添加了estimatedHeightForRow...方法后,调用顺序变成了:
使用预估高度后
也就是说,愿望实现了. 这个方法的出现使得tableView代理方法的调用顺序发生了改变,从而达到了前面说的"绘制cell时得到准确高度,然后把高度再拿给tableView去显示"的目的.并且,这个方法避免了一开始调用n次heightForRow的方法导致的一些不必要的计算.
现在让我们整理一下tableView在这段时间是怎么工作的:
- 首先tableView会先向代理拿得到每个cell的预估高度(estimatedHeightForRow...方法),并且拿这个高度去计算整个tableView应该显示的范围
- 根据每行预估的高度,算出一屏显示的cell的个数,并先对这些cell(调用cellForRow...方法)进行绘制
- 在绘制时拿到cell的真实高度,然后放在heightForRow...方法里面拿给tabelView去用
- 屏幕滚动(有cell进入屏幕)的时候,仍然会调用绘制以及获取真实高度的方法.
简单点说,就是预估高度用来让tableView心里有个底,把cell先绘制出来,但最后实际的cell高度还是会从heightForRow...方法中获取.
网友评论