Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting a RootViewController with UINavigationController Programmatically

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?

like image 650
Adam Avatar asked Feb 11 '15 15:02

Adam


2 Answers

  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

like image 195
Saif Avatar answered Nov 15 '22 06:11

Saif


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()
like image 34
User558 Avatar answered Nov 15 '22 05:11

User558