Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIViewController.navigationController becomes nil

I bumped into a problem where UIViewController.navigationController becomes nil and I'm desperately trying to find an answer to this one.

The UINavigationController gets setup in the application delegate:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    self.rootViewController = [[RootViewController alloc] initWithNibName:@"RootView" bundle:nil];

    UINavigationController* navigationController = [[UINavigationController alloc] initWithRootViewController:self.rootViewController];
    [self.window addSubview:navigationController.view];

    [self.window makeKeyAndVisible];

    return YES;
}

When the RootViewController is appearing, the self.navigationController member is set and I can use it to hide the navigation bar, like so:

- (void)viewWillAppear:(BOOL)animated {
    NSLog( @"self = %@, self.navigationController = %@", self, self.navigationController );
    [self.navigationController setNavigationBarHidden:YES animated:NO];
}

The debug output shows values for self and self.navigationController.

When a button is clicked in this controller, self remains the same value indeed but self.navigationController is now nil:

- (IBAction)buttonClicked:(id)sender {
        NSLog( @"self = %@, self.navigationController = %@", self, self.navigationController );
        // here, self.navigationController is nil, so
        // [self.navigationController pushViewController:...] doesn't work :-(
}

I've seen dozens of questions regarding this problem and the answer is always that the UIViewController is not part of a UINavigationController. Since accessing the navigationController in viewWillAppear works fine, I believe something else must be going on. Do you have any pointers? I'll happily provide more detail if necessary.

like image 281
digitalbreed Avatar asked Dec 15 '25 16:12

digitalbreed


2 Answers

Try this in the app delegate:

[(UINavigationController *)self.window.rootViewController pushViewController:yourViewController animated:NO];

the rootviewcontroller is actually UINavigationController if you po to debug it. This works for me.

like image 131
ning Avatar answered Dec 19 '25 05:12

ning


Your code shows that you are only using the navigationController's view but just pray that navigationController life is handled by some magic hand which is not the case.

You need someone to be the explicit owner of the navigationController here.

In fact, the following line:

[self.window addSubview:navigationController.view];

seems to indicate that what you want is for the window's rootViewController to be navigationController:

self.window.rootViewController = navigationController;

But also, it seems that the application's delegate is to be an owner of navigationController as well so navigationController should, in fact, be an ivar of your app's delegate.

In short, fix your object graph (and it will coincidentally do the extra retain you manually did and fix your bug)

like image 40
Julien Avatar answered Dec 19 '25 07:12

Julien



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!