Selected UItableViewCell staying blue when selected

IphoneObjective CUitableviewUinavigationcontroller

Iphone Problem Overview


When I push a view after a user has selected a UITableView row, the row gets a blue highlight, and then the new view appears. That's fine. But when I go 'back' the row is still highlighted in blue. Here's my didSelectRowAtIndexPath code.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
	SettingsViewController *controller = [[SettingsViewController alloc] initWithNibName:@"SettingsView" bundle:nil];
	[[self navigationController] pushViewController:controller animated:YES];
	[controller release], controller = nil;	
}

What am I doing wrong?

Iphone Solutions


Solution 1 - Iphone

As the answers above point out, you need to explicitly deselect the row. You have two options as to how you do this. The first, is to deselect the row immediately after selection:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
  ...
  [tableView deselectRowAtIndexPath:indexPath animated:YES];
}

That will work just fine, but there is an alternative, and its the approach taken by UITableViewController which is to leave the row selected then deselect it when the view re-appears (after the controller you're pushing is popped off of the stack).

This has the slight advantage that the user sees a glimpse of their previous selection when they return so they can see what they had selected previously.

To implement this, you just need to override viewWillAppear:

- (void)viewWillAppear:(BOOL)animated
{
  [super viewWillAppear:animated];
  [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
}

As I said, this is what the default of implementation of UITableViewController's viewWillAppear: does so if you are using UITableViewController and not seeing this behaviour, you should check that you are calling the super implementation in your class' own viewDidAppear:.

Update (30 Oct 2013): well, this is a popular answer! As Ben rightly points out in the comments, UITableViewController actually does this in viewWillAppear: not viewDidAppear: - this is the correct timing. In addition, you turn this behaviour on and off using the clearsSelectionOnViewWillAppear property of UITableViewController. I've amended my answer above to reflect this.

Solution 2 - Iphone

UITableViewController has a BOOL property called clearsSelectionOnViewWillAppear which does exactly what you want.

By default it is set to YES, but I've noticed that you can (sometimes accidentally) disable this property by implementing your own viewWillAppear: method. I think this is because the deselection happens during [UITableViewController viewWillAppear:] which might never get called if you override it.

The solution is easy, then. Just call super's version of viewWillAppear: somewhere in your version of that method:

- (void)viewWillAppear:(BOOL)animated {
  // Your custom code.
  [super viewWillAppear:animated];
}

Apple recommends always calling the super version of any of the view{Did,Will}{A,Disa}ppear methods if you override them.

References

Solution 3 - Iphone

You need to deselect it:

[tableView deselectRowAtIndexPath:indexPath animated:YES];

Solution 4 - Iphone

If your controller is based on UITableViewController, you get this feature for free. But I often ended up using UIViewController with no. of other controls in addition to UITableView, in that case, you should override your viewWillAppear to

-(void) viewWillAppear:(BOOL)animated{
    // Unselect the selected row if any
	NSIndexPath*	selection = [devListTableview indexPathForSelectedRow];
	if (selection){
		[tableview deselectRowAtIndexPath:selection animated:YES];
	}
}

Solution 5 - Iphone

You just need to call [tableView deselectRowAtIndexPath: indexPath animated: YES].

Solution 6 - Iphone

The default behaviour of UITableViewController deselects the row when the user returns from the detail view. The response given by Luke is fine, but I want to point out the reason for it:

1- If you have your UITableViewController like it was when you created it from scratch, you will have all the default behaviours.

2- If in the situation 1 you add a -viewWillAppear or -viewDidAppear, then you will be overwriting the standard behaviour. Them, if you want that the row deselects on return, you must say the super explicitly that you'd like it to deselect the row by himself as it always did! To achieve this, as Luke says, you must call [super viewWillAppear:animated] or [super viewDidAppear:animated] like this:

-(void)viewWillAppear:(BOOL)animated {
    
    [super viewWillAppear:animated];
    
	// Here goes all of your stuff
}

Solution 7 - Iphone

This solution is for swift

To solve this problem just add tableView.deselectRow(at: indexPath, animated: false) in didSelectRowAt indexPath function .

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
}

Watch this 1 minute video tutorial to visualize .

Solution 8 - Iphone

Another solution is to call UITableView's reloadData in viewWillAppear

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioncannyboyView Question on Stackoverflow
Solution 1 - IphoneLuke RedpathView Answer on Stackoverflow
Solution 2 - IphoneTylerView Answer on Stackoverflow
Solution 3 - IphonepkananenView Answer on Stackoverflow
Solution 4 - IphonepalanirajaView Answer on Stackoverflow
Solution 5 - IphoneBen GottliebView Answer on Stackoverflow
Solution 6 - IphoneRuben MarinView Answer on Stackoverflow
Solution 7 - IphoneAbdullah Mohammad DaihanView Answer on Stackoverflow
Solution 8 - IphoneAndy AView Answer on Stackoverflow