Swift - Pushviewcontroller from Appdelegate, Rootviewcontroller.Navigationcontroller Is Nil

Swift - pushViewController from appDelegate, rootViewController.navigationController is nil

It seems that rootViewController actually is of type UINavigationController in my case, so casting it on declaration allowed me to call pushToViewController directly on it.

func application(application: UIApplication, openURL url: NSURL, sourceApplication: String, annotation: AnyObject?) -> Bool {
let rootViewController = self.window!.rootViewController as! UINavigationController
let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
let profileViewController = mainStoryboard.instantiateViewController(withIdentifier: "InstructionVC") as! InstructionVC
rootViewController.pushViewController(profileViewController, animated: true)
return true

}

Unable to navigate to UIViewController from AppDelegate

Here is how I resolved the issue after 24hrs of struggle. The only thing I tried was "Used Try Catch Block" and the error was that I was not using the correct identifier name which was causing null pointer exception.
Here is the code:

@try {
UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
MultipleMarkersVC *vc = [sb instantiateViewControllerWithIdentifier:@"MultipleMarkersVC"];
UINavigationController *navCon = [[UINavigationController alloc] initWithRootViewController:vc];
[self.window.rootViewController presentViewController:navCon animated:YES completion:nil];
}
@catch (NSException * e) {
NSLog(@"Exception: %@", e);
}

swift navigation controller return nil after changing rootviewcontroller

You have removed your navigation controller from the view hierarchy. Let's look at the code you posted:

let appDelegate = UIApplication.shared.delegate as! AppDelegate
let destVC = self.storyboard?.instantiateViewController(withIdentifier: "home_view")
let rootViewController = appDelegate.window?.rootViewController as! UINavigationController
// at this point your window's root view controller is a navigation controller.
appDelegate.window?.rootViewController = destVC
// In the above, you replaced the navigation controller with your destVC.

It's like you took your sneaker off to put on your dress shoe, then you are asking why your sneaker isn't on your foot anymore.


The solution is to put a navigation controller in between your tab bar controller and the view controller that needs a navigation controller.

How to push a view controller from App Delegate on didReceiveRemoteNotification in Swift?

I managed to get it working as I needed with help from both Sh_Khan and the answer I found in this thread: How can I show ViewController in UITabBarController?

My initial view controller is a tabBar and therefore, this is the correct code for me:

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

let info = userInfo as NSDictionary
let name: String = info.value(forKey: "view-controller") as! String

switch name {
case "controller1":
let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
let controller1VC = storyboard.instantiateViewController(withIdentifier: "controller1VC") as! Controller1VC
let tabBar = self.window?.rootViewController as? UITabBarController
let nav = tabBar?.selectedViewController as? UINavigationController
nav?.pushViewController(controller1VC, animated: true)
default:
print("Nothing")
}
}

So this code will essentially convert the tabBar to a UINavigationController allowing for a pushViewController to work.

I hope this helps anyone else.

self.navigationController is always nil

You are instantiating the OrdersVC instead of instantiating the navigation controller into which it is embedded and which is the "initial" view controller of your storyboard. Use instantiateInitialViewController instead of using the identifier.

let nav = storyboard.instantiateInitialViewController()
self.window!.rootViewController = nav

The reason for the confusion is that you are "unlinking" the initial view controller from the storyboard with your login controller. You have to add the initial view controller back to the main window.

UIViewController.navigationController becomes nil

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)

Cannot push viewcontroller from appdelegate

Do like this

What did you assign VC for UITabBarController ? I bet UIViewController? Try assign UINavigationController instead of UIViewController

synthesize UINavigationController *navController;

self.navController = [[UINavigationController alloc] init];
SomeViewController *viewController = [[SomeViewController alloc] initWithNibName:@"SomeViewController" bundle:nil];
self.navController.viewControllers = [NSArray arrayWithObject:viewController];

UITabBarController *tabBarController = [[UITabBarController alloc] init];
[tabBarController setViewControllers:[NSArray arrayWithObjects:
self.navController, nil]];

Then on your actionsheet

[self.navController pushViewController:v2 animated:YES];

EDIT for storyboard

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
self.navController = (UINavigationController*) [storyboard instantiateViewControllerWithIdentifier:@"MyNavController"];

Hope that helps



Related Topics



Leave a reply



Submit