There's an annoying bug that I can't fix.
I have a CustomCell
, and in it I have a subview that changes it's color according to object's value.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = @"CustomCell";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
MyObject *object = [self.fetchedResultsController objectAtIndexPath:indexPath];
if ([object.redColor isEqualToNumber:[NSNumber numberWithBool:YES]]) {
cell.colorView.backgroundColor = [UIColor redColor];
}
else {
cell.colorView.backgroundColor = [UIColor clearColor];
}
return cell;
}
This is all working fine except when I delete a row with redColor = YES
from the tableview, and I scroll to show rows that was not visible. The first row that becomes visible (first row that reuses the reusable cell) has red color, even though that row is redColor = NO
. And if I scroll again and hide the cell and then show it again, color is set to clearColor, the way it should be.
I think this is because it's reusing the cell that has just been deleted.
So I'm trying to reset cell's content before reusing.
In CustomCell.m
- (void)prepareForReuse {
[super prepareForReuse];
self.clearsContextBeforeDrawing = YES;
self.contentView.clearsContextBeforeDrawing = YES;
self.colorView.backgroundColor = [UIColor clearColor];
}
But this is not working. Apple Doc says
The table view's delegate in tableView:cellForRowAtIndexPath: should always reset all content when reusing a cell.
What is the proper way to reset content? Do I have to remove subviews from the superview?
Thanks in advance
dequeueReusableCell(withIdentifier:)Returns a reusable table-view cell object after locating it by its identifier.
'Preparing for re-use' means checking, cleaning or repairing recovery operations, by which products or components of products that have become waste are prepared so that they can be re-used without any other pre-processing.
prepareForReuse()Prepares a reusable cell for reuse by the table view's delegate.
This seems to work.
I remove the cell's contentView when prepareForReuse in CustomCell.m
- (void)prepareForReuse {
[super prepareForReuse];
// Clear contentView
BOOL hasContentView = [self.subviews containsObject:self.contentView];
if (hasContentView) {
[self.contentView removeFromSuperview];
}
}
Add it in again in cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Cell
static NSString *cellIdentifier = @"CustomCell";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
// Restore contentView
BOOL hasContentView = [cell.subviews containsObject:cell.contentView];
if (!hasContentView) {
[cell addSubview:cell.contentView];
}
// Configure cell
MyObject *object = [self.fetchedResultsController objectAtIndexPath:indexPath];
if ([object.redColor isEqualToNumber:[NSNumber numberWithBool:YES]]) {
cell.colorView.backgroundColor = [UIColor redColor];
}
else {
cell.colorView.backgroundColor = [UIColor clearColor];
}
return cell;
}
Hope this will help someone.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With