6

I have a program with a Navigation Controller and a default RootViewController. If I do nothing programmatically, the app launches and the RootViewController works as I expect, such as what the storyboard below denotes:

enter image description here

The issue that I have is by incorporating the Optional Start ViewController. What I want is this: In my AppDelegate (didFinishLaunchingWithOptions), I want to have code like this:

UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"OptionalStartViewController"];
self.window.rootViewController = viewController;
[self.window makeKeyAndVisible];

To first show the Optional Start ViewController. Then, after the user has finished with the Optional viewcontroller, they can then display the RootViewController.

So in the Optional Start ViewController, I've added code like this to show the Root View Controller:

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];
UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"RootViewController"];
[self appDelegate].window.rootViewController = viewController;
[[self appDelegate].window makeKeyAndVisible];

This all works except the RootViewController, when shown, does not have the navigation controls as expected (i.e. the view is shown without navigation controls).

I've also tried the code below (using UINavigationController instead of ViewController) with the same results...

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];
UINavigationController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"HomeViewController"];
[self appDelegate].window.rootViewController = viewController;
[[self appDelegate].window makeKeyAndVisible];

One other twist... there could be several optional start view controllers.

Any ideas?

7
  • So the problem is that the navigation bar is not there? Commented Feb 11, 2015 at 15:24
  • Use the identifier of the UINavigationController instead of the UIViewController(Root view controller). Commented Feb 11, 2015 at 15:27
  • Setting UINavigationController as root did work for me. Commented Feb 11, 2015 at 15:47
  • @gabbler... did you first set a different viewcontroller as the rootviewcontroller, and then show your actual rootviewcontroller later? What does your code look like? Commented Feb 11, 2015 at 16:16
  • In my storyboard, I set the optional view controller as the root, and in this optional view controller, I clicked a button to show the navigation controller, which worked. Commented Feb 11, 2015 at 16:20

3 Answers 3

6
  1. Delete the UINavigationController
  2. select the controller ("optional start view controller" in our case)
  3. click Editor >> Embed In >> Navigation Controller
  4. Now select the Navigation Controller and Right Side Utility area, Select the option Is Initial View Controller

If you want to change the root view controller dynamically then its better to do it programmatically, in didFinishLaunchingWithOptions, Get the window instance , initialize navigation controller with the root view controller and then set windows root view controller to navigation controller. Here is the code.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.

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

    OptionalFirstViewController *optionalFirstViewController = [[OptionalFirstViewController alloc] initWithNibName:@"OptionalFirstViewController" bundle:nil];
    UINavigationController *homeNavigationController = [[UINavigationController alloc] initWithRootViewController:optionalFirstViewController];
    [optionalFirstViewController release];
    self.window.rootViewController = homeNavigationController;
    [homeNavigationController release];
    [self.window makeKeyAndVisible];

    return YES;
}

and make sure that you uncheck Is Initial View Controller for all view controllers in story board

Hope this helps

Sign up to request clarification or add additional context in comments.

3 Comments

What if there are more than one optional start view controllers?
Well, then you just have to decide beforehand which one you want to show, and use it. That adds the complexity of your business rule to the above code.
Yes of course you need to know beforehand which controller to show as per your business logic , you can always keep the business logic in a separate class / method which returns an class name, and here you can initialise the required controller. This just adds one more line to above code.
2

Without using storyboard we can set programmatically in AppDelegate Class, just write down these lines of code in AppDelegate.

AppDelegate.h

@property (strong, nonatomic) UIStoryboard *storyboard;
@property (strong, nonatomic) UINavigationController *navigationController;

AppDelegate.m

if(self.window == nil)
    self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];

if(self.navigationController == nil)
    self.navigationController = [[UINavigationController alloc]init];

if(self.storyboard == nil)
    self.storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];

self.navigationController.navigationBarHidden = YES;

// Here we can check user is login or not also,

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
ViewController *ivc = [storyboard instantiateViewControllerWithIdentifier:@"ViewController"];
[self.navigationController pushViewController:ivc animated:YES];
self.window.rootViewController = ivc;


[self.window setRootViewController:self.navigationController];
[self.window makeKeyAndVisible];

In Swift Version

var window: UIWindow?
var storyBoard :UIStoryboard?
var navigationController : UINavigationController?
var mainController :MainViewController = MainViewController()

if window == nil {
        window = UIWindow(frame: UIScreen.main.bounds)
    }
    if navigationController == nil {
        navigationController = UINavigationController()
    }
    if storyBoard == nil {
        storyBoard = UIStoryboard(name: "Main", bundle:nil)
    }
    navigationController?.setNavigationBarHidden(true, animated: true)
    // storyboard with identifer
    mainController = storyBoard?.instantiateViewController(withIdentifier: "MainViewController") as! MainViewController
    navigationController?.pushViewController(mainController , animated: true)

    window?.rootViewController = navigationController
    window?.makeKeyAndVisible()

Comments

1

You can't set a new root view controller to UINavigationController after it is initialised. You should modify viewControllers array of UINavigationController according to your needs.

If you want the optional VC to be root VC, create @[optionalVC] and set it as viewControllers array of UINavigationController.

1 Comment

How do you do that? navigationController.viewControllers = [optionalVC, secondVC, thirdVC] Like this?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.