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 *) ...
随机推荐
- KING_Unity学习之UGUI_Canvas渲染顺序以及层次关系总结
http://blog.csdn.net/kingsea168/article/details/50252733 之前一直用NGUI开发界面,但看到现在的unity的新版本的UGUI也不错,这几天专门 ...
- U3D开发性能优化笔记(待增加版本.x)
http://blog.csdn.net/kaitiren/article/details/45071997 此总结由自己经验及网上收集整理优化内容 包括: .代码方面: .函数使用方面: .ui注意 ...
- Unity3d的批渲染 batch rendering
http://blog.csdn.net/leonwei/article/details/41942157 批渲染(Batch) batch render 是大部分引擎提高渲染效率的方法,基本原理就是 ...
- 进击python第三篇:基础
基础拾遗 序列解包 例: >>>x,y,z=1,2,3 >>>print x,y,z 1 2 3 交换变量也是没问题 >>>x,y=y,x > ...
- 利用Web服务生成产品编号 执行添加操作
为什么我想要执行添加操作,却添加不成功,系统提示我comm.ExecuteNonQuery有错误 已找到原因 在 string strsql = "insert into tb_goods( ...
- assembly x86(nasm)画三角形等图形的实现(升级版)
https://www.cnblogs.com/lanclot-/p/10962702.html接上一篇 本来就有放弃的想法,可是有不愿退而求次, 然后大神室友写了一个集海伦公式计算三角形面积, 三点 ...
- vue 生命周期钩子函数
实例中的生命周期钩子可以分为以下8种情况: beforeCreate: 实例刚被创建,vue所有属性都还不存在 created: 实例创建完成,但$el还不存在 beforeMount:挂载之前 mo ...
- Info.plist配置相关文件访问权限
<key>NSAppleMusicUsageDescription</key> <string>App需要您的同意,才能访问媒体资料库</string> ...
- [筆記]catalan卡特蘭數
前言:希望自己每個星期能發一篇文章,提升一下寫文章的能力?雖然對語文作文毫無幫助但是總比玩遊戲強 所以不務正業的東西就不放在首頁了,有興趣的可以點分類去看 來源:https://www.cnblogs ...
- [Chrome](CSS) 解决Chrome font-size 小于 12px 无效
Chrome中 font-size 小于 12px 会失效. 解决的办法一种是: -webkit-text-size-adjust:none; (但是Chrome27之后取消了支持) 利用CSS3的缩 ...