ios UITableViewCell重用问题
在写sina 微博界面的过程中使用到了cell,那么就是在cell上添加一些控件,但是由于每条微博的内容都是不同的,所以在显示的过程中,出现了内容重叠的问题,其实就是UITableViewCell重用机制的问题。
- - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
- {
- static NSString *CellIdentifier = @"Cell";
- UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
- if (cell == nil) {
- cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
- }
- return cell;
- }
TableView的重用机制,为了做到显示和数据分离,IOS tableView的实现并且不是为每个数据项创建一个tableCell。而是只创建屏幕可显示最大个数的cell,然后重复使用这些cell,对cell做单独的显示配置,来达到既不影响显示效果,又能充分节约内容的目的。
解决方法一:对在cell中添加的控件设置tag的方法
例如在微博内容中需要添加label,那么就可以对添加的label设置tag,然后新建cell的时候先remove前一个cell tag相同的label,再添加新的label,这样就不会出现cell内容的重叠。
[[cell viewWithTag:100] removeFromSuperview];
[[cell contentView] addSubview:contentLabel];
解决方法二:删除cell中的所有子视图
在实现微博界面中,一个cell会有多个控件(label,imageview...),按理说,对每一个控件都设置tag,按照第一种解决方法,应该是可以实现的。但是在实际运行过程中发现不行,还是会出现内容重叠的问题,所以采用第二种解决方法--在新建cell的时候,如果不是空就删除所有的子视图。
- if (cell != nil)
- {
- [cell removeFromSuperview];//处理重用
- }
解决方法三: 通过为每个cell指定不同的重用标识符(reuseIdentifier)来解决。
重用机制是根据相同的标识符来重用cell的,标识符不同的cell不能彼此重用。于是我们将每个cell的标识符都设置为不同,就可以避免cell重用问题了。
- - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
- {
- NSString *CellIdentifier = [NSString stringWithFormat:@"Cell%d%d", [indexPath section], [indexPath row]];//以indexPath来唯一确定cell
- UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; //出列可重用的cell
- if (cell == nil) {
- cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
- }
- //...其他代码
- }
这个方法还没实践过,先记录下来。
下面内容来自博客http://blog.csdn.net/omegayy/article/details/7356823
重用实现分析
查看UITableView头文件,会找到NSMutableArray* visiableCells,和NSMutableDictnery* reusableTableCells两个结构。visiableCells内保存当前显示的cells,reusableTableCells保存可重用的cells。
TableView显示之初,reusableTableCells为空,那么tableView dequeueReusableCellWithIdentifier:CellIdentifier返回nil。开始的cell都是通过[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]来创建,而且cellForRowAtIndexPath只是调用最大显示cell数的次数。
比如:有100条数据,iPhone一屏最多显示10个cell。程序最开始显示TableView的情况是:
1. 用[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]创建10次cell,并给cell指定同样的重用标识(当然,可以为不同显示类型的cell指定不同的标识)。并且10个cell全部都加入到visiableCells数组,reusableTableCells为空。
2. 向下拖动tableView,当cell1完全移出屏幕,并且cell11(它也是alloc出来的,原因同上)完全显示出来的时候。cell11加入到visiableCells,cell1移出visiableCells,cell1加入到reusableTableCells。
3. 接着向下拖动tableView,因为reusableTableCells中已经有值,所以,当需要显示新的cell,cellForRowAtIndexPath再次被调用的时候,tableView dequeueReusableCellWithIdentifier:CellIdentifier,返回cell1。cell1加入到visiableCells,cell1移出reusableTableCells;cell2移出visiableCells,cell2加入到reusableTableCells。之后再需要显示的Cell就可以正常重用了。
所以整个过程并不难理解,但需要注意正是因为这样的原因:配置Cell的时候一定要注意,对取出的重用的cell做重新赋值,不要遗留老数据。
一些情况
使用过程中,我注意到,并不是只有拖动超出屏幕的时候才会更新reusableTableCells表,还有:
1. reloadData,这种情况比较特殊。一般是部分数据发生变化,需要重新刷新cell显示的内容时调用。在cellForRowAtIndexPath调用中,所有cell都是重用的。我估计reloadData调用后,把visiableCells中所有cell移入reusableTableCells,visiableCells清空。cellForRowAtIndexPath调用后,再把reuse的cell从reusableTableCells取出来,放入到visiableCells。
2. reloadRowsAtIndex,刷新指定的IndexPath。如果调用时reusableTableCells为空,那么cellForRowAtIndexPath调用后,是新创建cell,新的cell加入到visiableCells。老的cell移出visiableCells,加入到reusableTableCells。于是,之后的刷新就有cell做reuse了。
ios UITableViewCell重用问题的更多相关文章
- 你真的了解UITableViewCell重用吗?
一:首先查看一下关于UITableViewCell重用的定义 - (nullable __kindof UITableViewCell *)dequeueReusableCellWithIdentif ...
- iOS UITableViewCell UITableVIewController 纯代码开发
iOS UITableViewCell UITableVIewController 纯代码开发 <原创> .纯代码 自定义UITableViewCell 直接上代码 ////// #imp ...
- iOS UITableViewCell的"滑动出现多个按钮"
本文授权转载,作者:@夏天是个大人了 前言: 本篇博客其实就是想介绍tableviewcell滑动的一些"事",昨天在逛github的时候看到的还挺有意思的三方库,简单用了一下感觉 ...
- UITableViewCell重用的问题
UITableView中有两种重用Cell的方法: - (id)dequeueReusableCellWithIdentifier:(NSString *)identifier; - (id)dequ ...
- UITableViewCell重用机制
UITableView是iOS开发中使用频率非常高的一个控件,它常被用来展示信息列表,尽管信息数据可能非常多,但UITableView消耗的资源却并不会随着展示信息的增多而变大,这都要得益于UITab ...
- 捉襟见肘之UITableViewCell重用引发的问题
我记录一下自己如何解决cell内容重叠的问题 首先,复习一下:http://blog.csdn.net/omegayy/article/details/7356823 UITableViewCell的 ...
- 禁用UITableViewCell 重用机制
有时候不想让Cell重用,怎么办勒.接下来介绍两种方法 方法一 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAt ...
- UITableviewCell 重用内存
转载自:http://www.cnblogs.com/tangbinblog/p/3371545.html 重用实现分析 查看UITableView头文件,会找到NSMutableArray* vi ...
- IOS Cell重用机制
重用机制: -(UITableViewCell *)tableView: (UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *) ...
随机推荐
- python 之 函数 装饰器
5.8 装饰器 1 开放封闭原则 软件一旦上线后,就应该遵循开放封闭原则,即对修改源代码是封闭的,对功能的扩展是开放的 也就是说我们必须找到一种解决方案: 能够在不修改一个功能源代码以及调用方式的前提 ...
- PyInstaller 库
将.py 源代码转换成无需源代码的可执行文件 首先,PyInstaller是第三方库,需要下载额外安装(安装第三方库需要使用pip工具) 步骤: 1.用管理员运行cmd命令行 "pip in ...
- [題解](縮點)luogu_P2341受歡迎的牛
對於每個強聯通分量,這些牛一定都互相喜歡,所以縮點(我也不知道怎麼想到的) 接下來就是統計答案,最後縮成了一個DAG圖,如果這個點是明星的話,其他每個點一定直接或間接的鏈接這個點 也就是說其他點一定有 ...
- python虚拟环境四
python虚拟环境管理器 我们在使用python虚拟环境的时候,最好安装一个虚拟环境管理器,这样我们就能很方便的管理python的 虚拟环境,而python的虚拟环境管理工具包就是virtualen ...
- 51nod 2133 排队接水
Bryce1010模板 http://www.51nod.com/onlineJudge/questionCode.html#!problemId=2133 #include <bits/std ...
- 093 Restore IP Addresses 复原IP地址
给定一个只包含数字的字符串,复原它并返回所有可能的IP地址格式.例如:给定 "25525511135",返回 ["255.255.11.135", " ...
- freertos之资源管理学习
OS下在对硬件外设资源操作.多任务的共享变量.任务和中断的共享变量操作时需要考虑资源的完整性和安全性. FREERTOS提供了临界区.调度器上锁.互斥量.优先级自动继承.创建守护任务的方法来改变最小优 ...
- python学习day11
目录 SqlAlchemy 外键 SqlAlechemy SQLAlchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API之上,使用关系对象映射进行数据库操作,简言之便是:将对象 ...
- React Native开发时devices offline和手机不能晃动的处理
1. adb device 显示 devices offline 可能重启adb server: $ adb kill-server $ adb start-server 2. 华为等手机不能 晃动显 ...
- 借助sass的Maps功能使得响应式代码更有条理
原文来自这里 本文综合了原文(by Jonathan Suh)以及笔者自己的理解. Introduction 众所周知,写代码与写维护性高的代码是两回事.而涉及到响应式,代码又特别容易变的杂乱.借助s ...