UITableView上拉加载更多的功能相信很多应用都会用到,类似朋友圈、微博这样的应用,tableView中的数据内容高度根据内容来变化,同时需要加载大量的数据(上拉加载更多),要怎样才能保证加载数据时的页面流畅呢?

UITableView的原理和使用,以及其滚动帧率的优化,不是本篇blog要讨论的问题,这个在网上能搜到大量资料,这里不再赘述。

一般在实现上拉加载更多数据的实现思路是:

1.获取新的数据

2.在当前dataArray中添加这些数据

3.在tableView上显示这些数据

其中第三步,可以通过insertRowsAtIndexPaths::或者reloadData这两种方式实现。

这里讨论使用reloadData的这种情况:

我们知道UITableView在滚动时会不断地调用

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath;

这两个方法,因此,要保证列表滚动的流畅性,最重要的就是优化这两个方法中的代码,保证代码的执行时间短。

而在加载更多数据时,在主动执行reloadData方法后,系统会重新计算一次所有cell的高度,也就是会根据cell数量在调用N次heightForRowAtIndexPath方法,当tableView中的数据较少,还可以接受,而当页面上数据加载较多时,即使heightForRowAtIndexPath方法执行效率再高,也无法避免出现UI卡顿的情况。

那么怎么办呢?

很简单,我们可以把cell的高度缓存下来在需要使用的时候取出,下面是实现的思路:

首先定义存储cell高度的模型,我们这里使用NSMutableDictionary,为什么不用NSMutableArray来做呢?稍后再说这个问题

   NSMutableDictionary* _cellHeightDictionary;

接着在heightForRowAtIndexPath中:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{ CGFloat cellHeight;
NSNumber* cellHeightNumber = [_cellHeightDictionary objectForKey:@(indexPath.row)];
if (cellHeightNumber) {//判断是否缓存了该cell的高度
cellHeight = [cellHeightNumber floatValue];
}else
{
cellHeight = [CustemCell cellHeightWithModel:_modelArray[indexPath.row]];//通过类方法获取cell高度
[_cellHeightDictionary setObject:@(cellHeight) forKey:@(indexPath.row)];//以indexPath为key存储cell高度
}
return cellHeight;
}

最后别忘了在重新刷新数据的时候清空cell高度的缓存。

这样修改完之后,不论页面加载了多少数据,每个cell的高度只需要计算一次,优化的目的也就达到了。

最后说一下为什么用NSMutableDictionary而不用NSMutableArray来存储cell height:

因为系统在调用heightForRowAtIndexPath是无序的,如果用数组来存数height,会导致高度错位和其他莫名其妙的问题,所以这里一定不能用数组来缓存高度。

UITableview优化随笔(1)-提高加载更多内容时的效率的更多相关文章

  1. PHP+Ajax点击加载更多内容 -这个效果好,速度快,只能点击更多加载,不能滚动自动加载

    这个效果好,速度快,只能点击更多加载,不能滚动自动加载 一.HTML部分 <div id="more"> <div class="single_item ...

  2. PHP+Ajax点击加载更多内容

    css样式: <style type="text/css"> #more{margin:10px auto;width: 560px; border: 1px soli ...

  3. jquery制作图片瀑布流点击按钮加载更多内容

    <script type="text/javascript" src="js/jquery-1.9.1.min.js"></script> ...

  4. Jquery鼠标滚动到页面底部自动加载更多内容,使用分页

    index.php代码   [html] view plaincopy <!DOCTYPE html PUBLIC ;}                .single_item{padding: ...

  5. 实现Android ListView 自动加载更多内容

    研究了几个小时终于实现了Android ListView 自动加载的效果. 说说我是怎样实现的.分享给大家. 1.给ListView增加一个FooterView,调用addFooterView(foo ...

  6. Jquery+php鼠标滚动到页面底部自动加载更多内容,使用分页

    1.index.php <style type="text/css"> #container{margin:10px auto;width: 660px; border ...

  7. [转]微信小程序之加载更多(分页加载)实例 —— 微信小程序实战系列(2)

    本文转自;http://blog.csdn.net/michael_ouyang/article/details/56846185 loadmore 加载更多(分页加载) 当用户打开一个页面时,假设后 ...

  8. 微信小程序之上拉加载更多

    loadmore 加载更多(分页加载) 当用户打开一个页面时,假设后台数据量庞大时,一次性地返回所有数据给客户端,页面的打开速度就会有所下降,而且用户只看上面的内容而不需要看后面的内容时,也浪费用户流 ...

  9. jQuery+php+Ajax文章列表点击加载更多功能

    jQuery+php+Ajax实现的一个简单实用的文章列表点击加载更多功能,点击加载更多按钮,文章列表加载更多数据,加载中有loading动画效果. js部分: <script type=&qu ...

随机推荐

  1. 解决 libnanomsg.so.0: cannot open shared object file: No such file or directory 无法找到libnanomsg动态链接库

    参考: [11]缺少动态连接库.so--cannot open shared object file: No such file or directory Importing Issues: cann ...

  2. ThinkPHP开发笔记-控制器

    1.下面就是一个典型的控制器类的定义: <?php namespace Home\Controller; use Think\Controller; class IndexController ...

  3. raid1磁盘更换---测试

    安装centos6.71. CentOS安装过程配raid.参考:http://www.360doc.com/content/13/1209/21/14661619_335823338.shtml. ...

  4. duff's device

    const duffDevice = (items, process) => { let iterations = Math.floor(items.length / 8); let start ...

  5. PHP stream相关协议及上下文选项和参数归纳

    支持的协议和封装协议 PHP 带有很多内置 URL 风格的封装协议,可用于类似 fopen(). copy(). file_exists() 和 filesize() 的文件系统函数. 除了这些封装协 ...

  6. Kafka消息文件存储

    在对消息进行存储和缓存时,Kafka依赖于文件系统.(Page Cache) 线性读取和写入是所有使用模式中最具可预计性的一种方式,因而操作系统采用预读(read-ahead)和后写(write-be ...

  7. CodeForces 55D Beautiful numbers (SPOJ JZPEXT 数位DP)

    题意 求[X,Y]区间内能被其各位数(除0)均整除的数的个数. CF 55D 有些时候因为问题的一些"整体性"而导致在按位统计的过程中不能顺便计算出某些量,所以只能在枚举到最后一位 ...

  8. python __new__和__init__

    转载:http://www.cnblogs.com/tuzkee/p/3540293.html 1 2 3 4 5 6 7 8 class A(object):     def __init__(se ...

  9. 010PHP基础知识——运算符(三)

    <?php /** * 位运算符: * 1:&按位与:左右两边的数,同位都为1,返回是1,否则返回是0 */ /*$a = 5; $b = 6; $a = decbin($a);//10 ...

  10. hdu1151

    题解: 二分图边覆盖 n-最大匹配 代码: #include<cstdio> #include<cmath> #include<algorithm> #includ ...