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. 从0开始 数据结构 字典树 hdu1251

    字典树 知识补充 '\0'和'\n'的区别 '\0' 是一个字符串的结尾 '\n' 是换行符 gets 和 scanf 的区别 gets()函数总结: gets() 从标准输入设备读取字符串,以回车结 ...

  2. 数据结构实习 - problem M 判断平衡二叉树

    writer:pprp date: 20171103 题目描述 给定一棵二叉树的中序和层序输出,判断是否为平衡二叉树的.如果是,输出YES如果不是输出NO. 输入 树结点个数 中序遍历序列 层序遍历序 ...

  3. LA 3971 组装电脑(二分)

    https://vjudge.net/problem/UVALive-3971 题意:你有b块钱,想要组装一台电脑.给出n个配件各自的种类.品质因子和价格,要求每种类型的配件各买一个,总价格不超过b, ...

  4. Codeforces Round #357 (Div. 2) 优先队列+模拟

    C. Heap Operations time limit per test 1 second memory limit per test 256 megabytes input standard i ...

  5. 完美解决 No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-android

    问题描述 好久之前的一个Android项目,最近需要重构一下 因为Android Studio的开发环境以及Gradle的版本等等都进行了一定的更新,于是导入Project以后,出现了报错: No t ...

  6. 002——vue小结

    1.new 一个vue对象的时候你可以设置他的属性,其中最重要的包括三个,分别是:data,methods,watch. 2.其中data代表vue对象的数据,methods代表vue对象的方法,wa ...

  7. linux 字符串查找

    获取指定目录文件名包含指定字符的文件,然后遍历是否有包含特定字符串,有的话打出文件名 #!/bin/sh COMMAND=`find /data/home/ftp/data/20/201704/27/ ...

  8. kvm虚拟机克隆注意点

    1.硬盘空间会受第一次分配硬盘是的max capacity(最大容量) 限制,如果额外添加一块硬盘,会多出一个img文件,克隆这种虚拟机,两个img文件会都克隆下来,如果不重新命名会在原先img文件后 ...

  9. dell c6220II lsi阵列卡

    1.如果在lsi阵列卡上有多个raid,那么需要在第一个创建的raid上装系统,或者说先创建装系统的raid,否则可能报 hard disk error(centos 6.6) 2.热插拔的后果:如果 ...

  10. java的简单入门,tomcat服务器

    Tomcat是一款开源的处理动态非常牛逼的web服务器.是sun公司开发的,在丧尸危机之后被收购了. 安装Tomcat需要的支持安装包 JDK下载:http://www.oracle.com/tech ...