9

i have several table views in my app. I am familiar with the usual behaviour of tables, that when you select a row and progress to a pushed view, it turnes blue, then when you go back it stays blue for a split second then fades to white, in order to notify the user of what row was just selected.

This worked perfectly up until recently when i noticed it no longer did the last bit of what I described: it didn't stay blue for that split second...

I have no idea why, but after reading a few related posts on this site i realised that the piece of code that does that gets called is in the "viewDidAppear" method. What confuses me is that I don't override this method, but i did test it with an NSLog to show me the index path for the row it should deselect, which returned (null).

So this is leading me to believe that somehow, the tableView is prematurely deselecting the row.

Below is my didSelectRowForIndexPath method:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"Selected row at index path: %@", indexPath);

    //setting our view controller as what we want
    TripDetails *detailViewController = [[TripDetails alloc] initWithNibName:@"TripDetails" bundle:nil];
    self.tripsDetailViewController = detailViewController;
    [detailViewController release];


 // Pass the selected object to the new view controller.
    NSLog(@"Passing trip...");
    self.tripsDetailViewController.selectedTrip =  [fetchedResultsController objectAtIndexPath:indexPath];

    //Hide the bottom bar on pushed view
    tripsDetailViewController.hidesBottomBarWhenPushed = YES;

   [self.navigationController pushViewController:tripsDetailViewController animated:YES];

}

Any help is greatly appreciated, thanks :)


EDIT: Fixed

I got it working.... Seems i was calling the [self.tableView reloadData] method in my viewWillAppear method which then caused the table to deselect all cells. Below is my modified viewDidLoad method. Thanks for the suggestions!

- (void)viewWillAppear:(BOOL)animated 
{
NSLog(@"running viewWIllAppear for TripsTable");

//Getting indexpath for highlighened cell, to rehighlight
NSIndexPath *selectedIndex = [self.tableView indexPathForSelectedRow];

//Refreshing Table - Implement an if statement on the condition that the data has     changed
[self viewDidLoad];
[self.tableView reloadData];

//Re select cell
[self.tableView selectRowAtIndexPath:selectedIndex animated:NO scrollPosition:UITableViewScrollPositionNone];


[super viewWillAppear:animated];
 }
Sonypop
  • 91
  • 1
  • 1
  • 4
  • 1
    Shot in the dark: Maybe the previous view controller is unloaded because of memory usage. This could lead to this behavior. – dasdom Jul 11 '11 at 11:19

7 Answers7

31

Its a feature you can turn off.

In the UITableViewController you can call

[ self setClearsSelectionOnViewWillAppear:NO ];

This is directly from the file "UITableViewController.h". This feature is documented there.

   @property(nonatomic) BOOL clearsSelectionOnViewWillAppear __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_3_2); 
// defaults to YES. If YES, any selection is cleared in viewWillAppear:
jankoen
  • 518
  • 5
  • 10
  • I was trying to find this property in the `UITableView` header :/ – rounak Jan 14 '15 at 10:00
  • 2
    Note that as of Xcode 6.3 / iOS 8.3, this setting does not persist when set in IB / storyboards / XIBs. You can check the box, but it is not properly initialized; it is always set to true. – Chris Conover May 28 '15 at 04:14
9

Try

[tableView deselectRowAtIndexPath:indexPath animated:NO];

for deselecting a row and

[tableView selectRowAtIndexPath:indexPath animated:NO];

for highlighting the selected row.

Praveen S
  • 10,355
  • 2
  • 43
  • 69
2

apparently viewWillAppear: of the class UITableView does deselect all cells, even without reloading the cells. The trick described worked for me:

code from my UITablViewController:

- (void)viewWillAppear:(BOOL)animated
{
    NSIndexPath *selectedIndex = [self.tableView indexPathForSelectedRow];

    [super viewWillAppear:animated];

    //Re select cell
    [self.tableView selectRowAtIndexPath:selectedIndex animated:NO scrollPosition:UITableViewScrollPositionNone];
};
jankoen
  • 518
  • 5
  • 10
  • That is what I was suspecting... Note to myself: don't ever use UITableViewController again! :p – Giovanni Jun 14 '14 at 14:12
  • 1
    This is incorrect and should be retracted. It is controlled by clearsSelectionOnViewWillAppear, see @jankoen's answer above (and my comment) – Chris Conover May 28 '15 at 04:15
1

Use this piece of code in the end of didSelectRowAtIndexPath delegate method of table view,

[tableView deselectRowAtIndexPath:indexPath animated:NO];
0
NSIndexPath *_selectedIndex ;

use the above global variable to store in selected in the table view delegate method

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
 _selectedIndex = [self.tableView indexPathForSelectedRow];
}

and in the following delegate of UINavigationController delegate method

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
[self.tableView selectRowAtIndexPath:_selectedIndex animated:NO scrollPosition:UITableViewScrollPositionNone];

}
Vinodh
  • 5,262
  • 4
  • 38
  • 68
0

I am not sure if this is relevant but there is a flag in UITableViewController I just noticed called

@property(nonatomic) BOOL clearsSelectionOnViewWillAppear NS_AVAILABLE_IOS(3_2); // defaults to YES. If YES, any selection is cleared in viewWillAppear:

I think this should solve some of the problems people are describing here.

ucangetit
  • 2,595
  • 27
  • 21
0

The following code does works Good

   -(void)viewWillAppear:(BOOL)animated{
         [super viewWillAppear:YES];
         [self setClearsSelectionOnViewWillAppear:NO ];
    }
ViJay Avhad
  • 2,684
  • 22
  • 26