Michael
Michael

Reputation:

indexPathForSelectedRow on previous UITableViews always returns nil?

I have a stack of UITableViews managed by a UINavigationController. When I try calling indexPathForSelectedRow on any of the previous UITableViews, I always get nil:

NSEnumerator *e = [[navigationController viewControllers] objectEnumerator];
UITableViewController *controller;
while (controller = [e nextObject]) {
    NSIndexPath *selectedIndexPath = [[controller tableView] indexPathForSelectedRow]; // always nil
    // ...
}

I can't find anything about this behavior in Apple's docs; is it intentional? If so, is there another way to do what I'm trying to do, without me having to resort to manually managing a redundant mySelectedIndexPath instance variable inside didSelectRowAtIndexPath or somesuch?

Upvotes: 1

Views: 3557

Answers (2)

Rob
Rob

Reputation: 4434

I was noticing this as well on the iPad, in a splitscreen view (left, right detail pane), and it's kinda annoying. However, I found that if you override viewWillAppear, you can get the selected row for the table view before you call [super viewWillAppear];

So if you had some code like this, indexPathForSelectedRow would be nil,

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    if(![_self.tableView indexPathForSelectedRow])
    {
        NSLog(@"nothing selected, so selecting 1st one");
            // sets the detail pane here. 
    }
}

but if the code was like this (note the viewWillAppear: at the end), then indexPathForSelectedRow would not be nil.

- (void)viewWillAppear:(BOOL)animated {
    if(![_self.tableView indexPathForSelectedRow])
    {
        NSLog(@"nothing selected, so selecting 1st one");
                // sets the detail pane here. 
    }
    [super viewWillAppear:animated];
}

Upvotes: 1

Darren
Darren

Reputation: 25619

A non-visible view in a UINavigationController stack can be unloaded at any time, therefore you can't rely on the state of non-visible views.

It's quite possible that the UITableViewController you're referencing would have already unloaded its table view, in which case calling [controller tableView] will instantiate a new view.

Upvotes: 1

Related Questions