David B.
David B.

Reputation: 314

NavigationController is null after setting RootViewController in Xamarin.iOS

I am using storyboards with Xamarin.iOS. The DashboardViewController (a UINavigationController) is set as the initial view in the storyboard. However, in my AppDelegate class, the FinishedLaunching method is conditionally checking if the user needs to login or not when the app starts up. If so, it will set the "ViewController" (login controller) as the RootViewController, or else it will instantiate the initial view controller as set by the storyboard, which is the "DashboardViewController". Here is the code for the FinishedLaunching method.

    public override bool FinishedLaunching (UIApplication application, NSDictionary launchOptions)
    {
        // Override point for customization after application launch.
        // If not required for your application you can safely delete this method

        Window = new UIWindow(UIScreen.MainScreen.Bounds);

        var storyboard = UIStoryboard.FromName("Main", NSBundle.MainBundle);

        bool isLoggedOut = true;
        UIViewController rootViewController;

        if (isLoggedOut)
            rootViewController = (UIViewController)storyboard.InstantiateViewController("ViewController");
        else
            rootViewController = (UIViewController)storyboard.InstantiateInitialViewController();

        Window.RootViewController = rootViewController;
        Window.MakeKeyAndVisible();
    }

Once the user's credentials are verified, the following code attempts to set the RootViewController again back to the original "DashboardViewController" and present that view. This is done from the login controller.

    partial void LoginBtn_TouchUpInside (UIButton sender)
    {
        var appDelegate = UIApplication.SharedApplication.Delegate as AppDelegate;
        appDelegate.SetRootViewController (dashboardViewController, true);
        this.PresentViewController (dashboardViewController, true, null);
    }

Here is the code for the "SetRootViewController" in the AppDelegate:

    public void SetRootViewController()
    {
        Window = new UIWindow(UIScreen.MainScreen.Bounds);
        var storyboard = UIStoryboard.FromName("Main", NSBundle.MainBundle);

        bool isLoggedOut = false;
        UIViewController rootViewController;

        if (isLoggedOut)
            rootViewController = (UIViewController)storyboard.InstantiateViewController ("ViewController");
        else 
            rootViewController = (UIViewController)storyboard.InstantiateViewController (viewController);

        Window.RootViewController = rootViewController;
        Window.MakeKeyAndVisible();
    }

This works so far, but if I try to add another view to the stack in the DashboardViewController (which is a UINavigationController), saying from a button click using the following code,

    partial void ProfileBtn_TouchUpInside (UIButton sender)
    {
        this.NavigationController.PushViewController (profileViewController, true);
    }

the NavigationController is null and the app crashes. So the basic flow for this scenario is "Set RootViewController to "ViewController" so the user can log in --> When the user logs in set the RootViewController back to the DashboardViewController and present that view --> Click a button to navigate to another view from DashboardViewController view but the NavigationController in DashboardViewController is null.

What am I doing wrong?? Any help or advice would be appreciated (and I apologize for the long question).

Upvotes: 3

Views: 6213

Answers (1)

David B.
David B.

Reputation: 314

I've decided to leave this question up for those that may come upon the same problem. I've figured out what I believe to be a solution. In my AppDelegate "SetRootViewController" method, instead of saying,

Window.RootViewController = rootViewController;

I needed to be saying,

Window.RootViewController = new UINavigationController(rootViewController);

with everything else staying the same. The workflow now works as expected. This is because the controller I am trying to set as the RootViewController is not just a UIViewController, it's a UIViewController wrapped by a UINavigationController. This answer is also reiterated here in the following link

https://forums.xamarin.com/discussion/23424/how-can-i-use-this-navigationcontroller-on-my-view

I apologize for answering my own question, if anybody has a better method or sees something wrong with this please let me know. Hope this helps someone in the future.

Upvotes: 9

Related Questions