Set rootViewController of UINavigationController by method other than initWithRootViewController
Asked Answered
L

5

92

How Do I set the rootViewController of UINavigationController by a method other than initWithRootViewController?

I want use initWithNavigationBarClass:toolbarClass: to deliver a custom toolbar for my NavigationController, so I don't think I can use initWithRootViewController.

Linguiform answered 25/4, 2013 at 12:40 Comment(1)
One approach I've just discovered is: [navigationController setViewControllers:[NSArray arrayWithObject:(Pointer to View Controller that should be the root view controller)]]; is this the best way? I assume you should only call this in the AppDelegate file at the didFinishLaunching delegate method, as it seems risky messing with UINavigationController's view controller array after thisLinguiform
B
168

You can solve this by calling setViewControllers.

Like this:

UINavigationController *navigationController = [[UINavigationController alloc] initWithNavigationBarClass:[MyNavigationBar class] toolbarClass:[UIToolbar class]];

[navigationController setViewControllers:@[yourRootViewController] animated:NO];

Swift version:

let navigationController = UINavigationController(navigationBarClass: MyNavigationBar.self, toolbarClass: UIToolbar.self)

navigationController.setViewControllers([yourRootViewController], animated: false)
Barabbas answered 25/4, 2013 at 12:45 Comment(5)
Thanks for confirming. This might need to go in a separate question but I assume the initWithNav.. means that all my toolbars will have the same appearance I set in the custom subclass. How do I then have different styled toolbars for different sections of my app? Do I return different toolbars from that custom subclass? Or is there a better approach?Linguiform
For that you can use navigationController.navigationBar.tintColor = [UIColor blackColor]; or however you want to style it in the -(void)viewDidAppear:animated: methods of your ViewControllersBarabbas
So this would override the fact that in my UIToolBar subclass I'm overriding drawRect and setting a custom background? This is how I implement this: UIImage *backgroundImage = [UIImage imageNamed:@"UIToolBar_Background.png"]; [backgroundImage drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];Linguiform
I'm not sure if it overrides as much as a drawRect customization, but its the default method for overriding the UIToolbar properties of a UINavigationController.Barabbas
Any idea on this follow up question I posted on an issue I'm encountering. #16216481Linguiform
S
30

Knowledge Sharing Using Swift:

Changing root view controller from class other than app delegate.swift

let appdelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
var homeViewController = mainStoryboard.instantiateViewControllerWithIdentifier("HomeViewController") as! HomeViewController
let nav = UINavigationController(rootViewController: homeViewController)
appdelegate.window!.rootViewController = nav

Hope this will helpful for someone.

Changing rootviewcontroller With Animation can be achieved with:

UIView.transitionWithView(self.window!, duration: 0.5, options: UIViewAnimationOptions.TransitionFlipFromLeft, animations: {
    self.window?.rootViewController = anyViewController
}, completion: nil)

We can write a generalised method too, similar to this.

Solidus answered 25/4, 2015 at 6:40 Comment(7)
hi @Arvind, can you tell me the best place to put this code? Should it be at the top of AppDelegate.swift so that the variables are globally available? Or perhaps it needs to be within a class somewhere since it's instantiating views? thanksCollarbone
Yes, you can use at func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool. Other than you can on any view controller. as you may required when you ask for logout.Solidus
@Arvind how to deal with animation? No animation is shown and the rootView is shown instantly.Giannagianni
@Engnyl: I have update the answer. Thanks for your query, that make it more updated.Solidus
getting nil on self.navigationControllerBrentonbrentt
This question is "Set rootViewController of UINavigationController by method other than initWithRootViewController" and your answer to use initWithRootViewController? Why?Meteorite
This answer changes the root view controller of the entire window though. The question spefically asks to set the root view controller of a single navigationcontroller.Barabbas
J
17

this one works for me, hope it helps you,

let rootVC:LoginViewController = self.storyboard?.instantiateViewControllerWithIdentifier("LoginViewController") as! LoginViewController
let nvc:UINavigationController = self.storyboard?.instantiateViewControllerWithIdentifier("RootNavigationController") as! UINavigationController
nvc.viewControllers = [rootVC]
UIApplication.sharedApplication().keyWindow?.rootViewController = nvc
Jerad answered 15/8, 2016 at 12:27 Comment(3)
you saved my day!Avidin
getting nil on self.navigationControllerBrentonbrentt
@WasimAhmed that mean you are not having navigation controller as root view controllerJerad
S
2

In swift 3.0 xcode8.1

in general settings delete in Main Interface: Main <-this after Main Interface:

class AppDelegate...

 var window: UIWindow?

    fun application...

      window = UIWindow(frame: UIScreen.main.bounds)
      window?.makeKeyAndVisible()
      window?.rootViewController = UINavigationController(rootViewController: NewYourController)
Saidee answered 1/11, 2016 at 20:50 Comment(1)
This does not answer the question. You're calling initWithRootViewController, exactly what the question is asking how to avoid.Septima
S
-3
  let storyboard = UIStoryboard(name: "Main", bundle: nil)         
  let yourNewRootView = storyboard.instantiateViewControllerWithIdentifier("yourNewRootView") as? yourNewRootView


   self.window = UIWindow(frame: UIScreen.mainScreen().bounds)

    UIView.transitionWithView(self.window!, duration: 0.1, options: [UIViewAnimationOptions.TransitionFlipFromRight,UIViewAnimationOptions.TransitionFlipFromLeft], animations: 
    {
        // animation

        }, completion: { (finished: Bool) -> () in

            self.window?.rootViewController = nil
            self.window?.rootViewController = yourNewRootView
            self.window?.makeKeyAndVisible()
    })
Seditious answered 12/1, 2016 at 13:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.