4

There are three viewController, MainViewController ViewControllerB and ViewControllerC. MainViewController will be loaded when the app launch.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // Override point for customization after application launch.

    self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen] bounds]];

    MainViewController * main = [[MainViewController alloc]init];
    UINavigationController * navigationController = [[UINavigationController alloc]initWithRootViewController:main];
    self.window.rootViewController = navigationController;
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
    return YES;       
}

and there is a button on the MainViewController, present ViewControllerB,

UIViewController *rootViewController = [[UIApplication sharedApplication].keyWindow rootViewController];
ViewControllerB * vcb=[[ViewControllerB alloc] init];
[rootViewController presentViewController:vcb animated:YES completion:nil];

After the ViewControllerB appear, click the button push ViewControllerC. but the navigationController is nil. It can't push ViewControllerC

[self.navigationController pushViewController:vcC animated:YES];
Ashley Mills
  • 50,474
  • 16
  • 129
  • 160
Ran
  • 303
  • 1
  • 3
  • 15
  • 1
    You did `presentViewController:animated:completion:`, so that's normal. Didn't you wanted to do `[self.navigationController pushViewController:vcb animated:YES];` instead? – Larme Apr 24 '18 at 12:27
  • @Larme Actually vcB is a section and vcC is sub section of B. So I use present at first.Is there any solution? – Ran Apr 24 '18 at 13:23
  • 1
    You need to embed `ViewControllerB` in a `UINavigationController` or it won't have a navigationController itself. Then `UINavigationController * navigationController = [[UINavigationController alloc]initWithRootViewController:vcb]; [rootViewController presentViewController:vcb animated:YES completion:nil];` – Larme Apr 24 '18 at 13:26
  • thank you ,It seems work. But do you mean [rootViewController presentViewController:navigationController animated:YES completion:nil] ? It's a little different from your code @Larme – Ran Apr 24 '18 at 13:47
  • 1
    That's what I meant, I forgot to replace `vcb` copy/pasting the last line. – Larme Apr 24 '18 at 13:54
  • Here is another question, why the ViewController navigationController is nil when using present? @Larme – Ran Apr 24 '18 at 15:04

1 Answers1

8
  1. You have the MainViewController (mvc), which is embedded in a NavigationController;

  2. Then, on mvc you have the following code:

    [rootViewController presentViewController:vcb animated:YES completion:nil];

    You are calling presentViewController on the current ViewController, which will modally present the next ViewController, in this case ViewControllerB (vcb);

  3. Finally, you try to access the NavigationController inside ViewControllerB (vcb) in order to push ViewControllerC (vcc), with the following code:

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

The problem is that vcb is not aware of the NavigationController, since presentViewController presents the view controller modally, outside the existing navigation stack. Thus, resulting in a nil NavigationController in vcb.

You can refer to https://stackoverflow.com/a/14233252/9323816 for more information.

Kévin
  • 850
  • 7
  • 13