estimatedRowHeight
为什么要引入estimatedRowHeight
呢?顾名思义就是预估高度。在预估高度之前,与高度相关的属性及方法比较常用的有以下两个:
* rowHeight
:这个属性适合用于拥有固定高度的tableview
,这种方式比较高效,滚动时没有任何高度计算,可以得到较好的滚动体验。
* tableview:heightForRowAtIndexPath:
这种方式适用于tableview
需要根据不同的内容展示不同高度的cell
,在该方法中计算得出cell
高度。但是这种方式的缺点也很明显,即使你有20,000行的cell,系统也会在tableview加载的时候提前获取所有cell的高度。延长了tableview
的加载时间。
文档中对estimatedRowHeight
的解释是这样的:提供一个非负的预估行高可以提高tableview的加载速度。如果一个tableview中包含可变的行高,当tableview加载数据时,会去计算所有的行高,这个代价是很大的。使用预估高度的话,你就可以将一些计算工作从加载时间推迟到滚动时间。
我们都知道,创建一个UIScrollView
,需要设置它的contentSize
,才可以正确的显示,tableview
也一样,tableview在创建了之后,需要知道即将展示在tableview
中展示的数据个数以及每条数据内容决定的cell
的高度,这样才能计算得到其contentSize
,得到contentSize
之后,才能正确得显示。因此,如果你实现了tableview:heightForRowAtIndexPath:
的代理方法,tableview
会在加载阶段调用所有的cell
对应的该方法(设置不止一次地调用),去计算contentSize
。如果你在高度计算的代理方法中进行了很复杂的计算,那么你很可能会在页面出现好久,才看到的tableview
显示。因此,预估高度的出现,使得加载时不需要去计算所有cell
对应的真实高度,而是使用预估高度计算得出一个预估的contentSize
,在你滚动tableview
的时候,随着cell
不断滚入屏幕,cell
的高度也被计算出来,这个时候tableview.contentSize
再根据不断计算得出的cell
的真实高度来进行调整。这么做的高处是,你不需要等好久才看到tableview
展示出来了。但是缺点也很明显,你本可以在加载时候将所有cell
的高度计算并缓存,这样滚动时就不需要再进行计算,直接取得缓存高度酒可以,但是预估高度的存在,使得在滚动时才会去计算cell
高度,滚动体验会受到影响。这个时候,还是不要开启预估高度的好。另外,tableview
在不断调整自己的contentSize
的过程中,右侧的indicator
会出现突然变化或者跳跃的现象。
下面一组数据反应了iOS不同系统版本中关于预估高度作出的改变:(见ppt中的数据)
由此得出下面几个结论:
* 不使用预估高度时初始计算高度计算次数很高,远大于数据的数量
* 使用预估高度之后初始高度计算次数大大减小,优化了tableview加载的时间
* 除了iOS7之外,8-9在继续滚动时依旧会计算cell高度
iOS8中苹果推荐使用动态字体,也就是用于可以在设置中调整字体大小,这样一来,你的cell
即使已经加载了数据,高度也是会发生变化的,因此在iOS8之后,即使tableview
的cell
高度已经计算过,只要你不停滚动,计算也不会停止。
self-sizing cells
假设我们正在滚动一个tableview
,此时第四行cell
即将出现在屏幕上,在这个cell
被创建之前,我们所知道的只有它的预估高度,继续滚动,当cell
即将出现在屏幕上时,被创建出来,然后系统会去问cell
要它的size,如果这个size
不同于之前的estimatedRowHeight
的值,系统会对tableview.contentSize
进行调整,调整之后,cell就会出现在屏幕上了。
因此,self-sizing
也就是说让cell
自己负责计算自己的高度,那么cell
如何决定自己的高度呢?有以下三种方法:
- Auto Layout
- Override sizeThatFits()
- Override preferredLayoutAttributesFittingAttributes()
值得注意的是,对cell
设置约束时,需要把cell
的宽高都指定好。如果你的tableview
是通过nib或者storyboard
创建的,cell
会有一个默认高度,这个时候一定不要忘了下面这行代码:
tableview.rowHeight = UITableViewAutomaticDimension;
这也就意味着高度tableview
,我没有行高,你需要根据其他的信息得出行高。
UICollectionViewFlowLayoutAutomatic
这是iOS10中为estimatedItemSize
新增的一个值。iOS10以前,你会设置你的estimatedItemSize
为一个具体的预估大小,在你滚动UICollectionView
的过程中,这个预估大小一直被用于未创建的cell
,没有变化。在iOS10中,如果你设置了
layout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize;
UICollectionView
在为你计算cell
的预估大小,并且,随着cell
不断被加载出来,这个预估大小也会不断调增,逐渐调整为一个最为接近的值,这就为我们解决了有时候不知道设置一个怎样的预估大小的问题。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)