UITableView selection not sticking when reloading cells
I have some UITableView code that was setting a selection, and then later making some other changes to the cell using reloadRowsAtIndexPaths:withRowAnimation: and I was having trouble figuring out why my selection wasn't sticking. I'd select an object, but it wouldn't show as selected.
Turns out reloadRowsAtIndexPaths:withRowAnimation: will deselect whatever rows you reload. Check this out:
[cc lang="objc"]
// Create an NSIndexPath that indicates the 3rd row
NSIndexPath *path = [NSIndexPath indexPathForRow:3 inSection:0];
// Select it
[self.tableView selectRowAtIndexPath:path
animated:NO
scrollPosition:UITableViewScrollPositionNone];
// Is it still selected?
path = self.tableView.indexPathForSelectedRow;
// Yes, this will print the values you'd expect for that row being selected
NSLog(@"Path: %@", path);
// Reload that row
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:path] withRowAnimation:UITableViewRowAnimationNone];
// Now is it still selected?
path = self.tableView.indexPathForSelectedRow;
// Negatory, path is null.
NSLog(@"Path: %@", path);
[/cc]
It's not obvious from the documentation that this operation affects the selection, and it took me a while to figure out why my selection was being dropped. The fix is simple enough: Preserve the selection yourself around the reload call.
[cc lang="objc"]
// Save the current selection
NSIndexPath *savedSelection = self.tableView.indexPathForSelectedRow;
// Reload
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:path] withRowAnimation:UITableViewRowAnimationNone];
// And restore the selection
[self.tableView selectRowAtIndexPath:savedSelection
animated:NO
scrollPosition:UITableViewScrollPositionNone];
[/cc]