Search code examples
objective-cioscocoa-touchdelegatespushviewcontroller

Can't figure out how to use UINavigationControllerDelegate and pushViewController together in a UIViewController


I have a UIViewController that conforms to several delegates - shown below:

@interface SpotController : UIViewController <UITabBarDelegate, UITableViewDelegate, UITableViewDataSource, MKMapViewDelegate, UIActionSheetDelegate, UINavigationControllerDelegate>

For some reason the NavigationControllerDelegate portion is not working. I'm not sure what I'm doing wrong. Basically I'm trying to push to a new ViewController when the tableView's row is selected. I have the following code:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{    
    NSIndexPath *selectedIndexPath = [tableView_ indexPathForSelectedRow];

    // do some stuff here to prep/set stuff on the destination VC

    DetailsVC *detailsVC = [self.storyboard instantiateViewControllerWithIdentifier:@"detailsVC"];
    [self.navigationController pushViewController:detailsVC animated:YES];
}

So, like I said, the pushViewController does not work, meaning I do not get sent to the destination VC. I just go no where.

Note: This exact code worked perfectly if I embed the ViewController in a NavigationController (I.E. Select the VC in the StoryBoard, then Editor | Embed In | Navigation Controller). but I don't want to do it this way.

I've also tried creating an @property of type UINavigationController, and then alloc-init it in the viewDidLoad. I tried both the init and the initWithRootViewController:self versions of that method but neither worked. Not sure if I'm even doing that right.

Perhaps I need to specify the @property as a delegate explicitly? Not sure how to do that, I've tried doing the following:

@synthesize navController = navController_;
- (void)viewDidLoad
{
    [super viewDidLoad];        
    navController_ = [[UINavigationController alloc] init]; // initWithRootViewController:self];
    [navController_ setDelegate:self];
}

But still nothing.

PS - I'm using Xcode 4.3 w/ ARC & Storyboard.


Solution

  • You can't ask a navigation controller to push new view controllers if it isn't on the screen.

    Note: This exact code worked perfectly if I embed the ViewController in a NavigationController (I.E. Select the VC in the StoryBoard, then Editor | Embed In | Navigation Controller). but I don't want to do it this way.

    This way, your navigation controller exists and is on the screen. Why don't you want to do it this way?

    I've also tried creating an @property of type UINavigationController, and then alloc-init it in the viewDidLoad. I tried both the init and the initWithRootViewController:self versions of that method but neither worked. Not sure if I'm even doing that right.

    This won't work as the navigation controller isn't controlling what is on the screen, it is just existing in memory.

    In short, you can't push view controllers onto and off a navigation stack unless you have an active navigation stack, and without embedding your VC in a navigation controller, you don't have one. Reconsider your design. You have to embed your VC in a navigation controller if you want to use the features of a navigation controller.