Question

I am toggling a background image on a UITableViewCell on a right swipe. The problem is that if I add [taskManager reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationRight]; it will only toggle once but then not toggle back. So why is this? What will make this not happen? Here is the whole method code.

- (void)handleSwipeRight:(UISwipeGestureRecognizer *)gestureRecognizer {
CGPoint location = [gestureRecognizer locationInView:self.taskManager];

NSIndexPath *indexPath = [self.taskManager indexPathForRowAtPoint:location];

[taskManager reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationRight];

UIImage *notCkDone = [UIImage imageNamed:@"UITableViewCellCheckmark"];
UIImage *isCkDone = [UIImage imageNamed:@"UITableViewCellCheckmarkDone"];

UIImage *notBgDone = [UIImage imageNamed:@"UITableViewCell"];
UIImage *isBgDone = [UIImage imageNamed:@"UITableViewCellDone"];

UITableViewCell *cell = [taskManager cellForRowAtIndexPath:indexPath];

if (indexPath) {
    if (cell.imageView.image == notCkDone) {
        cell.imageView.image = isCkDone;
        cell.backgroundView = [[UIImageView alloc] initWithImage:isBgDone];
    } else {
        cell.imageView.image = notCkDone;
        cell.backgroundView = [[UIImageView alloc] initWithImage:notBgDone];
    }
    cell.textLabel.textColor = [UIColor colorWithRed:0.0/0.0 green:0.0/0.0 blue:0.0/0.0 alpha:1.0];
}

}

Was it helpful?

Solution

All changes to the visuals of your cells should happen inside your tableView:cellForRowAtIndexPath:. You should not do it in the event handler of your gesture recognizer (or anywhere else outside the tableView:cellForRowAtIndexPath, for that matter).

The gesture recognizer needs to alter the model behind your table view, so that your tableView:cellForRowAtIndexPath could make a decision to set the image to notCkDone or isCkDone the next time the data is reloaded, and also deal with the background changes. Then your gesture recognizer should tell the table view to reload the data.

Your current solution operates on cells returned by tableView:cellForRowAtIndexPath. When you change the visuals from the outside, the table view shows the change while the cell is on screen. However, when the cell scrolls off the screen, it gets recycled, meaning that the next time you dequeue a cell with cell identifier you may get an object that used to display as a different cell.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top