We often want to let users tap on a UITableViewCell
and then push a view controller onto the navigation controller. A straightforward way is to do this:
@implementation MyViewController
- (void)tableView:(UITableView*)aTableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
[aTableView deselectRowAtIndexPath:indexPath animated:YES];
[self.navigationController pushViewController:[SomeOtherViewController new] animated:YES];
}
@end
This works, but if you launch the Settings app, tap on a cell to push a view controller and then pan the view controller to reveal the previous view controller, you'll notice the cell selection (General in the screenshot) animates nicely as you pan. The implementation above doesn't produce that effect.
We can of course create this more polished effect. The trick is to not call -deselectRowAtIndexPath:animated:
immediately in -tableView:didSelectRowAtIndexPath:
when you are going to push a view controller. And then perform the deselection in -viewWillAppear
. You'll end up with:
@implementation MyViewController
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:animated];
}
- (void)tableView:(UITableView*)aTableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
//If you have cells that don't trigger pushing a view controller,
//you'll still want conditionally deselect those here
//[aTableView deselectRowAtIndexPath:indexPath animated:YES];
[self.navigationController pushViewController:[SomeOtherViewController new] animated:YES];
}
@end
If you use UITableViewController or subclass it, you will already get the implementation in -viewWillAppear for free if the clearsSelectionOnViewWillAppear property is set to YES. You will still need to call -deselectRowAtIndexPath:animated: for those case when you don't push a view controller though.
Your feedback is valuable: Do you want more nuggets like this? Yes or No
.
.