我是在什么情况下设置cell选中无效的
错误的代码大概是这样的
@implementation TableViewCell
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
if (selected) {
[self displaySelectedUI];
}else {
[self displayDefaultUI];
}
}
我重写了cell
的setSelected: animated:
方法,在其中切换cell
选中和非选中的样式.
@implementation ViewController
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSModel *model;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
[cell setSelected:model.selected animated:NO]
}
我无需关心用户点击cell
时cell
对于选中状态的切换,因为tableVIew
已经做了默认操作,但是当刷新tableView
时,之前的选中状态就不见了.
为了保存选中状态不被刷新掉,我在模型中使用selected
保存cell
的选中状态,在tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
协议触发时使用[cell setSelected:model.selected animated:NO]
恢复cell的选中状态
运行的时候出现问题了.无论我做多少次尝试,选中状态就像没有保存一样,每次刷新就会恢复成未选中状态.
解决办法
原文地址:http://www.jianshu.com/p/0668ce0b46b8
最终的解决方案是因为我看到评论中的这段话
断忆残缘
可以在主UI线程空闲时调用这个方法:- (void)selectRowAtIndexPath:(nullable NSIndexPath *)indexPath animated:(BOOL)animated scrollPosition:(UITableViewScrollPosition)scrollPosition,来设置选中
于是我将代码做了以下更改
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSModel *model;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
// 使用异步方法将设置cell选中状态推迟到tableView loadData完成
dispatch_async(dispatch_get_main_queue(), ^{
[cell setSelected:model.selected animated:NO]
});
}
原因分析
tableView reloadDate
会将所有的cell
恢复成未选中状态,任何在reloadData
方法执行完毕之前设置的选中状态都会失效.所以使用异步的方式将设置选中状态推迟到下一次runLoop
,这样cell
的选中状态就不会被tableView
重置