ios UITableView中Cell重用机制导致内容重复解决方法
-
UITableView继承自UIScrollview,是苹果为我们封装好的一个基于scroll的控件。上面主要是一个个的 UITableViewCell,可以让UITableViewCell响应一些点击事件,也可以在UITableViewCell中加入 UITextField或者UITextView等子视图,使得可以在cell上进行文字编辑。
UITableView中的cell可以有很多,一般会通过重用cell来达到节省内存的目的:通过为每个cell指定一个重用标识符 (reuseIdentifier),即指定了单元格的种类,当cell滚出屏幕时,会将滚出屏幕的单元格放入重用的queue中,当某个未在屏幕上的单 元格要显示的时候,就从这个queue中取出单元格进行重用。
但对于多变的自定义cell,有时这种重用机制会出错。比如,当一个cell含有一个UITextField的子类并被放在重用queue中以待重 用,这时如果一个未包含任何子视图的cell要显示在屏幕上,就会取出并使用这个重用的cell显示在无任何子视图的cell中,这时候就会出错。
解决方法:
方法1 将获得cell的方法从- (UITableViewCell*)dequeueReusableCellWithIdentifier: (NSString*)identifier 换为-(UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath
重用机制调用的就是dequeueReusableCellWithIdentifier这个方法,方法的意思就是“出列可重用的cell”,因而 只要将它换为cellForRowAtIndexPath(只从要更新的cell的那一行取出cell),就可以不使用重用机制,因而问题就可以得到解 决,虽然可能会浪费一些空间。
示例代码:
[plain]
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
// UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; //改为以下的方法
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; //根据indexPath准确地取出一行,而不是从cell重用队列中取出
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
//...其他代码
}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
// UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; //改为以下的方法
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; //根据indexPath准确地取出一行,而不是从cell重用队列中取出
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
//...其他代码
}方法2 通过为每个cell指定不同的重用标识符(reuseIdentifier)来解决。
重用机制是根据相同的标识符来重用cell的,标识符不同的cell不能彼此重用。于是我们将每个cell的标识符都设置为不同,就可以避免不同cell重用的问题了。示例代码:
[plain]
- (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];
}
//...其他代码
}- (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];
}
//...其他代码
}方法3 删除重用cell的所有子视图
这个方法是通过删除重用的cell的所有子视图,从而得到一个没有特殊格式的cell,供其他cell重用。
示例代码:
[plain]
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; //出列可重用的cell
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
else
{
//删除cell的所有子视图
while ([cell.contentView.subviews lastObject] != nil)
{
[(UIView*)[cell.contentView.subviews lastObject] removeFromSuperview];
}
}
//...其他代码
}
ios UITableView中Cell重用机制导致内容重复解决方法的更多相关文章
- 解决UITableView中Cell重用机制导致内容出错的方法总结
UITableView继承自UIScrollview,是苹果为我们封装好的一个基于scroll的控件.上面主要是一个个的 UITableViewCell,可以让UITableViewCell响应一些点 ...
- iOS - UITableView中Cell重用机制导致Cell内容出错的解决办法
"UITableView" iOS开发中重量级的控件之一;在日常开发中我们大多数会选择自定Cell来满足自己开发中的需求, 但是有些时候Cell也是可以不自定义的(比如某一个简单的 ...
- iOS解决UITableView中Cell重用带来的问题
tableView的常规配置,当超出一屏的cell就会标上可重用的标识出列到可重用缓存池中,后面再根据可重用标识来到的可重的cell就会和前面显示同样内容. - (UITableViewCell *) ...
- iOS之UITableView中的cell因为重用机制导致新的cell的数据出现重复或者错乱
UITableView中的cell可以有很多,一般会通过重用cell来达到节省内存的目的:通过为每个cell指定一个重用标识符(reuseIdentifier),即指定了单元格的种类,当cell滚 ...
- IOS Table中Cell的重用reuse机制分析
IOS Table中Cell的重用reuse机制分析 技术交流新QQ群:414971585 创建UITableViewController子类的实例后,IDE生成的代码中有如下段落: - (UITab ...
- UITableView中cell里的UITextField不被弹出键盘挡住
UITableView中cell里的UITextField不被弹出键盘挡住 本人视频教程系类 iOS中CALayer的使用 效果如下: 源码: EditCell.h 与 EditCell.m // ...
- UITableView中cell点击的绚丽动画效果
UITableView中cell点击的绚丽动画效果 本人视频教程系类 iOS中CALayer的使用 效果图: 源码: YouXianMingCell.h 与 YouXianMingCell.m / ...
- 如何获取UITableView中cell的frame值
如何获取UITableView中cell的frame值 这个可以用来处理UITableView弹出键盘的问题 本人视频教程系类 iOS中CALayer的使用 效果: 源码: // // ViewC ...
- 测试SDWebImage淡入淡出效果在UITableView中的重用显示问题
测试SDWebImage淡入淡出效果在UITableView中的重用显示问题 这个是在上一篇教程的基础上所添加的测试环节! 效果图(从效果图中看是没有任何重用问题的): 源码: ImageCell.h ...
随机推荐
- JAX-WS HandlerChain使用具体解释
JAX-WS的Handler和Servlet的Filter相似,能够对全部WebServicer进行拦截,在Handler中能够记录日志.权限控制.对请求的SOAP消息进行加密.解密等.JAX-WS提 ...
- C# WINFORM判断程序是否运行,且只能运行一个实例(转)
判断程序是否已经运行,使程序只能运行一个实例有很多方法,下面记录两种, 方法1:线程互斥 static class Program { private static System.Threading. ...
- spine 所有动画的第一帧必须把所有能K的都K上
spine 所有动画的第一帧必须把所有能K的都K上.否则在快速切换动画时会出问题.
- jquery动态生成html代码 怎么 获取id 或 class
动态创建的节点要用live方法加事件,语句要改为: $(“.del").live("click", function() { alert("获取到了" ...
- Mysql中count(*),DISTINCT的使用方法和效率研究
在处理一个大数据量数据库的时候 突然发现mysql对于count(*)的不同处理会造成不同的结果 比如执行 SELECT count(*) FROM tablename 即使对于千万级别的数据mysq ...
- spring boot test中mockito的运用
mock的意义 在微服务盛行的当下,开发过程中往往出现A应用中某功能的实现需要调用B应用的接口,无论使用RPC还是restful都需要B应用提供接口的实现整个开发工作才能继续进行.从而导致A应用的开发 ...
- IronPython使用
C#: class Program { static void Main(string[] args) { ScriptEngine engine = Python.CreateEngine(); S ...
- ios界面跳转
import Foundationimport UIKit class MyViewController: UIViewController{ // var window: UIWindow? ove ...
- Redis的字典扩容与ConcurrentHashMap的扩容策略比较
本文介绍Redis的字典(是种Map)扩容与ConcurrentHashMap的扩容策略,并比较它们的优缺点. (不讨论它们的实现细节) 首先Redis的字典采用的是一种‘’单线程渐进式rehash‘ ...
- 基于jQuery select下拉框美化插件
分享一款基于jQuery select下拉框美化插件.该插件适用浏览器:IE8.360.FireFox.Chrome.Safari.Opera.傲游.搜狗.世界之窗.效果图如下: 在线预览 源码下 ...