UITableView和UICollectionView的cell重用问题

APP的一个页面用到了自定义的UITableViewCell,由于iOS框架的cell重用机制,遇到了一个BUG,总结一下

现象

自定义的UITableViewCell里有一个UIButton,点击这个button以后,需要改变cell的样式,包括换UILabel字体颜色,禁用该UIButton等。结果发现,点击按钮之后,不仅当前cell的字体颜色变了,还有另外几个cell的字体颜色也跟着变,而且是随机的

原因

后来想到,应该是由于iOS的cell重用机制造成的,原来的代码类似:

-(void) onButtonPressed
{
    label.textColor = [UIColor grayColor];
    button.enabled = NO;
}

其中label和button都是这个cell的实例变量,由于cell是自动重用的,所以其他重用此cell的格子也会跟着一起变

正确的做法

修改之后,正确的做法应该是:

1、在controller中找到此cell对应的模型

2、修改模型对应的值

3、调用tableView的reloadData方法

4、在dataSource的代理方法里,再调用cell上的设置样式的方法

示意代码:

-(void) voteButtonPressed
{
    [myController voteWithCell:self];
}
-(void) voteWithCell:(CandidateTableViewCell*)cell
{
    RankingView *myView = (RankingView*)self.view;

    // 找到对应的模型
    NSIndexPath *indexPath = [myView.tableView indexPathForCell:cell];
    Candidate *candidate = [candidates objectAtIndex:indexPath.row];

    // 设置新值
    candidate.voteCount++;
    candidate.isVoted = YES;

    // 触发数据加载
    [myView.tableView reloadData];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    CandidateTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:[CandidateTableViewCell reuseIdentifier] forIndexPath:indexPath];
    Candidate *candidate = [candidates objectAtIndex:indexPath.row];
    [cell setCandidate:candidate isExpired:self.stage != 1 controller:self];
    return cell;
}
时间: 2024-10-14 19:27:56

UITableView和UICollectionView的cell重用问题的相关文章

学习IOS开发UI篇--UITableView/数据模型嵌套/UITableViewCell/Cell的重用

1.UITableView ================================================== UITableView有两种格式:group和plain 2.UITableView如何展示数据 ================================================== UITableView需要一个数据源(dataSource)来显示数据 凡是遵守UITableViewDataSource协议的OC对象,都可以是UITableView的

iOS UITableView的cell重用标识

转自   http://www.2cto.com/kf/201308/238449.html UITableView继承自UIScrollview,是苹果为我们封装好的一个基于scroll的控件.上面主要是一个个的 UITableViewCell,可以让UITableViewCell响应一些点击事件,也可以在UITableViewCell中加入 UITextField或者UITextView等子视图,使得可以在cell上进行文字编辑. UITableView中的cell可以有很多,一般会通过重用

UITableView的cell重用标识

转自   http://www.2cto.com/kf/201308/238449.html UITableView继承自UIScrollview,是苹果为我们封装好的一个基于scroll的控件.上面主要是一个个的 UITableViewCell,可以让UITableViewCell响应一些点击事件,也可以在UITableViewCell中加入 UITextField或者UITextView等子视图,使得可以在cell上进行文字编辑. UITableView中的cell可以有很多,一般会通过重用

解决UITableView中Cell重用机制导致内容出错的方法总结

UITableView继承自UIScrollview,是苹果为我们封装好的一个基于scroll的控件.上面主要是一个个的 UITableViewCell,可以让UITableViewCell响应一些点击事件,也可以在UITableViewCell中加入 UITextField或者UITextView等子视图,使得可以在cell上进行文字编辑. UITableView中的cell可以有很多,一般会通过重用cell来达到节省内存的目的:通过为每个cell指定一个重用标识符 (reuseIdentif

iOS8自动调整UITableView和UICollectionView布局

本文讲述了UITableView.UICollectionView实现self-sizing cell布局的知识,以及如何用InvalidationContext优化UICollectionView布局的更新. 背景 iOS越来越人性化了,用户可以在设置-通用-辅助功能中动态调整字体大小了.你会发现所有iOS自带的APP的字体大小都变了,可惜我们开发的第三方APP依然是以前的字体.在iOS7之后我们可以用UIFont的preferredFontForTextStyle:类方法来指定一个样式,并让

RumTime实践之--UITableView和UICollectionView缺省页的实现

有关RunTime的知识点已经看过很久了,但是一直苦于在项目中没有好的机会进行实际运用,俗话说"光说不练假把式",正好最近在项目中碰到一个UITableView和UICollectionView在数据缺省的情况下展示默认缺省页的需求,这个时候RunTime大展拳脚的时候就到了. 大致的实现思路是这样的,因为UITableView和UICollectionView都是继承自系统的UIScrollView,所以为了同时实现UITableView和UICollectionView的缺省页,我

iOS 8自动调整UITableView和UICollectionView布局

本文讲述了UITableView.UICollectionView实现 self-sizing cell 布局的知识,以及如何用 InvalidationContext 优化 UICollectionView 布局的更新. 背景 iOS 越来越人性化了,用户可以在设置-通用-辅助功能中动态调 “” 阅读器 UITableViewUICollectionView (via:玉令天下的Blog) 本文讲述了UITableView.UICollectionView实现 self-sizing cell

iOS中TableViewController的cell重用出错(内容错乱)

iOS中TableViewController的cell重用出错(内容错乱) - 简书 时间 2016 用我的双手,成就你的梦想 ---栋哥 今天我的心爱的程序又出现bug,对于我这个小菜来说,不得不说是非常苦恼的,主要是cell加载的时候因为重用池的问题而出现各种的bug,虽然程序没有崩掉,但是大大影响到我的心情,下面是最主要的一个问题 ,就是cell的重用问题, cell因为从重用池中调取,没有及时删除上面的内容而导致内容的各种出现, 这里有几个解决方案. UITableView继承自UIS

封装Button ,封装UITableView,封装UICollectionView

---恢复内容开始--- 封装Button ,封装UITableView,封装UICollectionView: 1.实现Button的创建和点击事件不用分开操作处理; 2.实现UITableView的代理数据源方法不用分开操作; 3.实现UICollectionView的代理数据源方法不用分开操作; 实现如下 : Button的实现 : - (void)viewDidLoad{ [super viewDidLoad]; self.view.backgroundColor = [UIColor