tableview和collectionView都有复用机制,设置collectionview是强制要求使用的。但是复用的时候往往在处理不当的时候会出现重影问题。
然而网上很多是给出这样的答案。
1、不使用重用机制;
2、每个cell指定不同的重用标识符;
3、 当cell存在的时候然后把最后一个存在子视图删除,大概代码是这样的:
while ([cell.contentView.subviews lastObject] != nil) { [(UIView *)[cell.contentView.subviews lastObject] removeFromSuperview]; }
这里我想说,你们真他妈在耍流氓啊,2和1有什么区别。好的就不吐槽了,个人思考问题不一样。
其实出现复用重影问题,基本都是由于在注册cell的时候,出现了判断的需要,造成了cell的形式多样,在拉动的时候,就出现了错乱,第N个cell的样式出现在第M个cell上。
解决这个就应该是解决注册cell时候是如何加载cell上面的东西,不管是数据还是UI。
解决方法,不要用tableview和cell的任何属性变量作为判断依据。因为在拉动tableview的时候,- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
在不断的调用,一旦出现复用机制,则没出现在屏幕上cell将会引用队列里相对应已存在的cell,而减少内存分配,而偏偏这时候会造成复用的cell上的判断值引用另一个cell上的值。所以把这些判断放在数据里面,用数据改变cell,而不是用cell自己的东西改变cell。
比如这里我创建了20个数据:
for (int i = 0; i < 20; i ++) { [self.sourceDataArr addObject: @"cell复用问题"]; }
而我在- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
是这样的
sourceCell * cell = [tableViewdequeueReusableCellWithIdentifier:@"cellID"];
if (!cell) {
cell = [[sourceCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cellID"];
}
if (indexPath.row%2 == 0) {
cell.backgroundColor = [UIColor grayColor];
}
cell.textLabel.text = self.sourceDataArr[indexPath.row];
return cell;
在为偶数的cell改变背景颜色,运行时是这样的。
数据错乱了。
而同样如果使用cell的变量或属性做判断值,也会出现复用重影
@interface sourceCell : UITableViewCell
@property (nonatomic , assign)BOOL isChange;
@end
我添加了一个属性,用cell上面的属性做判断。
但是如果我把判断放在数据源里。
for (int i = 0; i < 20; i ++) {
sourceModel * model = [sourceModel new];
model.cellString = @"cell复用问题";
if (i %2 == 0) {
model.color = [UIColor grayColor];
}
else
{
model.color = [UIColor whiteColor];
}
[self.sourceDataArr addObject: model];
}
而在- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
sourceCell * cell = [tableView dequeueReusableCellWithIdentifier:@"cellID"];
if (!cell) {
cell = [[sourceCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cellID"];
}
sourceModel * model = self.sourceDataArr[indexPath.row];
cell.textLabel.text = model.cellString;
cell.backgroundColor = model.color;
return cell;
效果是这样的。