Programmatically set the initial view controller using Storyboards
Asked Answered
T

25

268

How do I programmatically set the InitialViewController for a Storyboard? I want to open my storyboard to a different view depending on some condition which may vary from launch to launch.

Telmatelo answered 3/5, 2012 at 9:29 Comment(1)
Check this answer without warning, without clearing Main storyboard in settings.Bullock
M
481

How to without a dummy initial view controller

Ensure all initial view controllers have a Storyboard ID.

In the storyboard, uncheck the "Is initial View Controller" attribute from the first view controller.

If you run your app at this point you'll read:

Failed to instantiate the default view controller for UIMainStoryboardFile 'MainStoryboard' - perhaps the designated entry point is not set?

And you'll notice that your window property in the app delegate is now nil.

In the app's setting, go to your target and the Info tab. There clear the value of Main storyboard file base name. On the General tab, clear the value for Main Interface. This will remove the warning.

Create the window and desired initial view controller in the app delegate's application:didFinishLaunchingWithOptions: method:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];

    UIViewController *viewController = // determine the initial view controller here and instantiate it with [storyboard instantiateViewControllerWithIdentifier:<storyboard id>];

    self.window.rootViewController = viewController;
    [self.window makeKeyAndVisible];

    return YES;
}
Miriam answered 17/2, 2013 at 21:0 Comment(19)
Love! Love! Love! I will use this to switch between two completely different view controller trees for IOS6 and IOS7. Seems like the best way to handle backwards compatilibity, while still using all the bells and whistles in IOS7.Continuo
I am learning iOS programming in Swift. Can anyone help me how to write the above code in swift. please help. Thanks.Booster
Anyone who can answer why this is done in the didFinishLaunchingWithOptions method? I need to switch between onboarding/regular app and didFinishLaunchingWithOptions is only called when you install the app.Marabout
@Marabout didFinishLaunchingWithOptions is called when the app is started in a new process. If you go to the home screen and return to the app, this method will not be invoked again. (Unless iOS terminates due to memory constraints.) Try stopping the app and launch once again from your IDE. If problem continues, post the issue to SO and I'll be happy to help, friend.Miriam
you don't need to initialize the window, it's already initialized.Tineid
@peyman According to my investigation the window doesn't exist once the reference to the main storyboard is removed. I commented out the window instantiation in my current project and found this to still be the case.Miriam
I'm using this (well, a Swift version of it) and it's working well. However, I still get the "Failed to instantiate the default view controller for UIMainStoryboardFile 'Main' - perhaps the designated entry point is not set?" warning in the debug output. The app still runs fine. Is there a way to get rid of the warning? Do you get this warning? I put in a breakpoint and see that it has already appeared in the debug output before the didFinishLaunchingWithOptions code is hit.Telegraphone
@skypecakes the same with me. Did you manage to remove the warning?Yankeeism
@NunoGonçalves, I did get rid of the warning by setting an initial ViewController. It never actually gets loaded (breakpoint in viewDidLoad() never gets hit) unless my code in didFinishLaunchingWithOptions instantiates it, so this appears to be a fine solution.Telegraphone
But how to set Identifier of UIViewController?Agent
@Agent In Xcode 6.3.2, select the view controller in the Interface Builder, then in View>Utilities>Identity Inspector under 'Identity', set the 'Storyboard ID' to something useful.Stancil
@Raghav, here's the swift code: self.window = UIWindow(frame: UIScreen.mainScreen().bounds) var storyboard = UIStoryboard(name: "Main", bundle: nil) var viewController: UIViewController = // self.window!.rootViewController = viewController self.window!.makeKeyAndVisible()Dolichocephalic
I guess this can also be used to choose between (say) two different storyboards at launch time. One question is: If I intend to support State Preservation / State Restoration, perhaps I should move all that code to application:willFinishLaunchingWithOptions:?Decline
This will officially now be my default way of handling the "Login Conundrum" with UIStoryboards. It totally solved a very strange problem I was having with disappearing UIBarButtonItems, but that was because I was using a methodology that just felt really not-right to me (i.e. setting the viewControllers array in the navigation controller to replace its root view controller later in the sign-in view controller. bleh.).Sappanwood
Can you please check my question? #36768316Criollo
1) What happens if you don't type this line : ` [self.window makeKeyAndVisible]; `. 2) where does this line get hiddenly called when we simply use storyboardBarboza
@Travis. I did that but now the screen goes black for a few milliseconds before showing the view controller. Any ideas?Sensor
Just in case anyone else does what I did- don't delete the "Launch screen interface file base name" from the "Info" tab, or else your viewcontrollers won't initialize to the correct size (#42441123) Leaving that key alone is fine; you won't get any errors with it left in there.Esparza
In Xcode 12, you also have to remove the following value from the Info.plist file of the project : Application Scene Manifest > Scene Configuration > Application Session Role > Item 0 > delete Storyboard Name - Main. Otherwise you will have a crash during the app launch.Sweitzer
C
128

For all the Swift lovers out there, here is the answer by @Travis translated into SWIFT:

Do what @Travis explained before the Objective C code. Then,

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
    let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    var exampleViewController: ExampleViewController = mainStoryboard.instantiateViewControllerWithIdentifier("ExampleController") as! ExampleViewController

    self.window?.rootViewController = exampleViewController

    self.window?.makeKeyAndVisible()

    return true
}

The ExampleViewController would be the new initial view controller you would like to show.

The steps explained:

  1. Create a new window with the size of the current window and set it as our main window
  2. Instantiate a storyboard that we can use to create our new initial view controller
  3. Instantiate our new initial view controller based on it's Storyboard ID
  4. Set our new window's root view controller as our the new controller we just initiated
  5. Make our new window visible

Enjoy and happy programming!

Cimino answered 7/12, 2014 at 13:56 Comment(3)
i was ask @Miriam for this version , and then ... . thanks any way.Elated
Storyboard ID is under the Identity section in the Identity inspector paneImposition
A tip to not need storyboard ID is to set explicitly the initial view controller (rootViewController) in the storyboard, and use the instance method UIStoryboard.instantiateInitialViewController() to get the controller instead of UIStoryboard.instantiateViewControllerWithIdentifier() proposed above. The rest is the same.Vyner
E
47

You can programmatically set the key window's rootViewController in (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions

for example:

- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    if (shouldShowAnotherViewControllerAsRoot) {
        UIStoryboard *storyboard = self.window.rootViewController.storyboard;
        UIViewController *rootViewController = [storyboard instantiateViewControllerWithIdentifier:@"rootNavigationController"];
        self.window.rootViewController = rootViewController;
        [self.window makeKeyAndVisible];
    }

    return YES;
}
Emilieemiline answered 1/10, 2013 at 15:20 Comment(6)
How to then initiate the original entrypoint from the secondary UIViewController?Exuberate
@ooxio: you can store the original entrypoint in a global place then use it later on.Emilieemiline
this is really useful if you want to instantiate to login/register or something like that...Barboza
This is so much more straightforward than @Travis's answer above because you don't have to go messing with a million project settings and tinkering in IB. Who cares if one of your view controllers is technically the default initial VC and then you programmatically divert to a different one?Businessman
Note that the replaced, storyboard-designated initial View Controller will still get instantiated and go through the init() / deinit() cycle, but without executing viewDidLoad() or properly initializing IBOutlet-s. Make sure you code is ready for it.Jacobba
This is a great way to add support for iOS 11's UIDocumentBrowserViewController while conditionally maintaining support for iOS 10.x users via whatever existing mechanism was used.Haruspicy
G
21

SWIFT 5

If you don't have a ViewController set as the initial ViewController in storyboard, you need to do 2 things:

  1. Go to your project TARGETS, select your project -> General -> Clear the Main Interface field.
  2. Always inside project TARGETS, now go to Info -> Application Scene Manifest -> Scene Configuration -> Application Session Role -> Item0 (Default Configuration) -> delete the storyboard name field.

Finally, you can now add your code in SceneDelegate:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
    // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
    // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
    guard let windowScene = (scene as? UIWindowScene) else { return }

    window = UIWindow(windowScene: windowScene)


    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    // Make sure you set an Storyboard ID for the view controller you want to instantiate
    window?.rootViewController = storyboard.instantiateViewController(withIdentifier: identifier)
    window?.makeKeyAndVisible()

}
Geek answered 27/4, 2020 at 23:21 Comment(2)
This is certainly the most current answer as of Xcode 11.5, and indeed fixed the Failed to instantiate the default view controller for UIMainStoryboardFile 'Main' - perhaps the designated entry point is not set warning I was having after I decided to instantiate my initial VC in code. An important point, when @Geek says "delete the storyboard name field", they mean the whole row of the plist, not just the content of the field itself.Antabuse
Please note that UIWindow(windowScene: windowScene) is a different UIWindow initializer than the initWithFrame: you were probably using in older App Delegate-based code. Make sure to update that if you are porting to the new way of doing things. Using the old Window initializer was causing a black screen.Joashus
C
15

Swift 3: Update to @victor-sigler's code

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    self.window = UIWindow(frame: UIScreen.main.bounds)

    // Assuming your storyboard is named "Main"
    let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)

    // Add code here (e.g. if/else) to determine which view controller class (chooseViewControllerA or chooseViewControllerB) and storyboard ID (chooseStoryboardA or chooseStoryboardB) to send the user to

    if(condition){
        let initialViewController: chooseViewControllerA = mainStoryboard.instantiateViewController(withIdentifier: "chooseStoryboardA") as! chooseViewControllerA
        self.window?.rootViewController = initialViewController
    )
    }else{
        let initialViewController: chooseViewControllerB = mainStoryboard.instantiateViewController(withIdentifier: "chooseStoryboardB") as! chooseViewControllerB
        self.window?.rootViewController = initialViewController
    )

    self.window?.makeKeyAndVisible(

    return true
}
Cayuse answered 15/1, 2017 at 23:2 Comment(1)
Thank you, @MEK. Also, you may wish to correct the syntax of conditional closing statements by replacing trailing parentheses with braces.Pokey
W
10

You can set Navigation rootviewcontroller as a main view controller. This idea can use for auto login as per application requirement.

UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];

UIViewController viewController = (HomeController*)[mainStoryboard instantiateViewControllerWithIdentifier: @"HomeController"];

UINavigationController navController = [[UINavigationController alloc] initWithRootViewController:viewController];

 self.window.rootViewController = navController;

if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) {

    // do stuff for iOS 7 and newer

    navController.navigationBar.barTintColor = [UIColor colorWithRed:88/255.0 green:164/255.0 blue:73/255.0 alpha:1.0];

    navController.navigationItem.leftBarButtonItem.tintColor = [UIColor colorWithRed:88/255.0 green:164/255.0 blue:73/255.0 alpha:1.0];

    navController.navigationBar.tintColor = [UIColor whiteColor];

    navController.navigationItem.titleView.tintColor = [UIColor whiteColor];

    NSDictionary *titleAttributes =@{

                                     NSFontAttributeName :[UIFont fontWithName:@"Helvetica-Bold" size:14.0],

                                     NSForegroundColorAttributeName : [UIColor whiteColor]

                                     };

    navController.navigationBar.titleTextAttributes = titleAttributes;

    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];

}

else {

    // do stuff for older versions than iOS 7

    navController.navigationBar.tintColor = [UIColor colorWithRed:88/255.0 green:164/255.0 blue:73/255.0 alpha:1.0];



    navController.navigationItem.titleView.tintColor = [UIColor whiteColor];

}

[self.window makeKeyAndVisible];

For StoryboardSegue Users

UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];

// Go to Login Screen of story board with Identifier name : LoginViewController_Identifier

LoginViewController *loginViewController = (LoginViewController*)[mainStoryboard instantiateViewControllerWithIdentifier:@“LoginViewController_Identifier”];

navigationController = [[UINavigationController alloc] initWithRootViewController:testViewController];

self.window.rootViewController = navigationController;

[self.window makeKeyAndVisible];

// Go To Main screen if you are already Logged In Just check your saving credential here

if([SavedpreferenceForLogin] > 0){
    [loginViewController performSegueWithIdentifier:@"mainview_action" sender:nil];
}

Thanks

Weathers answered 7/10, 2015 at 15:22 Comment(0)
S
7

Open mainstoryboard, select the view that you want start first, then open Utilities--> Attributes. Below the "View Controller" you see the "Is initial View Controller" radio button. Just select it.

--- To the revised question:

May be you can try this: write a method in ViewDidLoad section of your inital view and when the method runs on application launch, method triggers a segue to another view.

Splatter answered 3/5, 2012 at 9:42 Comment(4)
I wrote the method in the ViewDidLoad but it didn't work and when I wright it in the viewdidAppear it is working, can you explain why this happening.Telmatelo
May be you should try this: Add a segue code according to your conditions to one of the appropriate methods in the appDelegate.m file. For example, you can add a segue code to the "applicationDidBecomeActive:" method.Splatter
@Jagdev you write it in ViewDidAppear instead of ViewDidLoad.Braiding
problem with this approach is the initial view controller appears becomes visible for some time and then switches to other which is not good from UX point of view so not a good solution.Ambition
D
3

I don't think it's possible. Instead you can have one initial controller which will have segues to different view controllers. On startup, you can decide which segue to perform programmatically.

Dextrin answered 3/5, 2012 at 10:11 Comment(0)
M
3

You can set initial view controller using Interface Builder as well as programmatically.

Below is approach used for programmatically.

Objective-C :

        self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
        UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];

        UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"HomeViewController"]; // <storyboard id>

        self.window.rootViewController = viewController;
        [self.window makeKeyAndVisible];

        return YES;

Swift :

        self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
        let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)

        var objMainViewController: MainViewController = mainStoryboard.instantiateViewControllerWithIdentifier("MainController") as! MainViewController

        self.window?.rootViewController = objMainViewController

        self.window?.makeKeyAndVisible()

        return true
Mutable answered 13/5, 2016 at 11:55 Comment(0)
S
3

In AppDelegate.swift you can add the following code:

let sb = UIStoryboard(name: "Main", bundle: nil)
let vc = sb.instantiateViewController(withIdentifier: "YourViewController_StorboardID")
self.window?.rootViewController = vc
self.window?.makeKeyAndVisible()

Of course, you need to implement your logic, based on which criteria you'll choose an appropriate view controller.

Also, don't forget to add an identity (select storyboard -> Controller Scene -> Show the identity inspector -> assign StorboardID).

Shannan answered 17/5, 2017 at 11:6 Comment(0)
W
3

Another solution with using Swift 3 and Swift 4 with avoiding force casting is like this

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    self.window = UIWindow(frame: UIScreen.main.bounds)
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    guard let viewController = storyboard.instantiateViewController(withIdentifier: "YourViewController") as? YourViewController else {
        return false
    }
    self.window?.rootViewController = viewController
    self.window?.makeKeyAndVisible()
    return true
}

And below is using with UINavigationController

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    self.window = UIWindow(frame: UIScreen.main.bounds)
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    guard let viewController = storyboard.instantiateViewController(withIdentifier: "YourViewController") as? YourViewController else {
        return false
    }
    let navigationController = UINavigationController(rootViewController: viewController)
    self.window?.rootViewController = navigationController
    self.window?.makeKeyAndVisible()
    return true
}
Wyck answered 4/8, 2017 at 9:26 Comment(0)
N
3

If you are using Scene Delegates in iOS 13+:

Make sure in your Info.plist file you find the row at:

Application Scene Manifest > Scene Configuration > Application Session Role > Item 0

and delete the reference to the Main Storyboard there as well. Otherwise you'll get the same warning about failing to instantiate from storyboard.

Also, move the code from the app delegate to the scene delegate method scene(_:willConnectTo:options:), since this is where life cycle events are handled now.

Newby answered 7/5, 2020 at 20:28 Comment(0)
U
2

I created a routing class to handle dynamic navigation and keep clean AppDelegate class, I hope it will help other too.

//
//  Routing.swift
// 
//
//  Created by Varun Naharia on 02/02/17.
//  Copyright © 2017 TechNaharia. All rights reserved.
//

import Foundation
import UIKit
import CoreLocation

class Routing {

    class func decideInitialViewController(window:UIWindow){
        let userDefaults = UserDefaults.standard
        if((Routing.getUserDefault("isFirstRun")) == nil)
        {
            Routing.setAnimatedAsInitialViewContoller(window: window)
        }
        else if((userDefaults.object(forKey: "User")) != nil)
        {
            Routing.setHomeAsInitialViewContoller(window: window)
        }
        else
        {
            Routing.setLoginAsInitialViewContoller(window: window)
        }

    }

    class func setAnimatedAsInitialViewContoller(window:UIWindow) {
        Routing.setUserDefault("Yes", KeyToSave: "isFirstRun")
        let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let animatedViewController: AnimatedViewController = mainStoryboard.instantiateViewController(withIdentifier: "AnimatedViewController") as! AnimatedViewController

        window.rootViewController = animatedViewController
        window.makeKeyAndVisible()
    }

    class func setHomeAsInitialViewContoller(window:UIWindow) {
        let userDefaults = UserDefaults.standard
        let decoded  = userDefaults.object(forKey: "User") as! Data
        User.currentUser = NSKeyedUnarchiver.unarchiveObject(with: decoded) as! User

        if(User.currentUser.userId != nil && User.currentUser.userId != "")
        {
            let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
            let homeViewController: HomeViewController = mainStoryboard.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
            let loginViewController: UINavigationController = mainStoryboard.instantiateViewController(withIdentifier: "LoginNavigationViewController") as! UINavigationController
            loginViewController.viewControllers.append(homeViewController)
            window.rootViewController = loginViewController
        }
        window.makeKeyAndVisible()
    }

    class func setLoginAsInitialViewContoller(window:UIWindow) {
        let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let loginViewController: UINavigationController = mainStoryboard.instantiateViewController(withIdentifier: "LoginNavigationViewController") as! UINavigationController

        window.rootViewController = loginViewController
        window.makeKeyAndVisible()
    }

  class func setUserDefault(_ ObjectToSave : Any?  , KeyToSave : String)
    {
        let defaults = UserDefaults.standard

        if (ObjectToSave != nil)
        {

            defaults.set(ObjectToSave, forKey: KeyToSave)
        }

        UserDefaults.standard.synchronize()
    }

    class func getUserDefault(_ KeyToReturnValye : String) -> Any?
    {
        let defaults = UserDefaults.standard

        if let name = defaults.value(forKey: KeyToReturnValye)
        {
            return name as Any
        }
        return nil
    }

    class func removetUserDefault(_ KeyToRemove : String)
    {
        let defaults = UserDefaults.standard
        defaults.removeObject(forKey: KeyToRemove)
        UserDefaults.standard.synchronize()
    }

}

And in your AppDelegate call this

 self.window = UIWindow(frame: UIScreen.main.bounds)
 Routing.decideInitialViewController(window: self.window!)
Unstopped answered 14/6, 2017 at 9:24 Comment(0)
S
1

A few days ago I've encountered to same situation. A very simple trick solved this problem. I set hidden my initial view controller before launch2. If initial view controller is the right controller it's set to visible in viewDidLoad. Else, a segue is performed to desired view controller. It works perfectly in iOS 6.1 and above. I'm sure it works on earlier versions of iOS.

Splatter answered 3/1, 2014 at 19:42 Comment(0)
C
1

Thanks modified this as follows in AppDelegate:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) ->     Bool {
//Some code to check value of pins

if pins! == "Verified"{
        print(pins)
        self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
        let mainStoryboard: UIStoryboard = UIStoryboard(name: "HomePage", bundle: nil)
        let exampleViewController: UINavigationController = mainStoryboard.instantiateViewControllerWithIdentifier("SBHP") as! UINavigationController

        self.window?.rootViewController = exampleViewController

        self.window?.makeKeyAndVisible()
    }else{
        print(pins)
        self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
        let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let exampleViewController: UINavigationController = mainStoryboard.instantiateViewControllerWithIdentifier("SBUser") as! UINavigationController

        self.window?.rootViewController = exampleViewController

        self.window?.makeKeyAndVisible()
    }
Chanukah answered 15/5, 2016 at 7:9 Comment(0)
B
1

Found simple solution - no need to remove "initial view controller check" from storyboard and editing project Info tab and use makeKeyAndVisible, just place

self.window.rootViewController = rootVC;

in

- (BOOL) application:didFinishLaunchingWithOptions:
Blockhead answered 1/10, 2016 at 5:48 Comment(1)
But you still get rootVC from instantiateViewControllerWithIdentifier, correct?Billie
A
1
let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc = mainStoryboard.instantiateViewController(withIdentifier: "storyBoardid") as! ViewController
let navigationController = UINavigationController(rootViewController: vc)
UIApplication.shared.delegate.window?.rootViewController = navigationController

Another way is to present viewController,

let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc = mainStoryboard.instantiateViewController(withIdentifier: "storyBoardid") as! ViewController
self.present(vc,animated:true,completion:nil)

First you need to create object of your storyboard then change root(if required) then you take reference of particular view controller which is pushed current view controller(if you change root) else it's just present new view controller which may you

Amphimixis answered 7/12, 2017 at 8:53 Comment(1)
@V D Purohit, can you describe more about your answer for more understanding.Derive
S
1

Swift 4, Xcode 9

in file AppDelegate.swift

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let firstVC = storyboard.instantiateViewController(withIdentifier: "firstViewController") as! firstViewController
    self.window?.rootViewController = firstVC
}
Sabotage answered 9/2, 2018 at 17:42 Comment(0)
L
1
 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        self.window = UIWindow(frame: UIScreen.main.bounds)
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        if (PreferenceHelper.getAccessToken() != "") {
            let initialViewController = storyboard.instantiateViewController(withIdentifier: "your View Controller Identifier")
            self.window?.rootViewController = initialViewController
        } else {
            let initialViewController = storyboard.instantiateViewController(withIdentifier: "your View Controller identifier")
            self.window?.rootViewController = initialViewController
        }
        self.window?.makeKeyAndVisible()
        return true
    }

/*
use your view Controller identifier must use it doubles quotes**strong text**
Lapwing answered 30/5, 2018 at 9:14 Comment(1)
checking on nsuser Defaults value preferences value Completly Stored and Checking Condition on in intial view Controller ProblemLapwing
S
1

Swift 5 or above# make route view controller by this simple code. If you are using xcode 11 or above first initialise var window: UIWindow? in AppDelegate

let rootVC = mainStoryboard.instantiateViewController(withIdentifier: "YOURCONTROLLER") as! YOURCONTROLLER

        navigationController.setNavigationBarHidden(true, animated: true)
        UIApplication.shared.windows.first?.rootViewController = UINavigationController.init(rootViewController: rootVC)
        UIApplication.shared.windows.first?.makeKeyAndVisible()
Sock answered 26/2, 2020 at 7:33 Comment(0)
O
1

If you prefer not to change applicationDidFinish, you can do the following trick:

Set Navigation controller as an initial view controller and assign to it a custom class 'MyNavigationController'. Then you can tweak its root view controller during viewDidLoad - it will override the root view controller that you set in your storyboard.

class MyNavigationController: UINavigationController {
    override func viewDidLoad() {
        super.viewDidLoad()
        if !isLoggedIn() {
            viewControllers = [R.storyboard.authentication.loginView()!]
        }
    }

    private func isLoggedIn() -> Bool {
        return false
    }

}
Objectivism answered 8/6, 2020 at 19:29 Comment(0)
C
0

Xcode 12.4 Swift 5

in SceneDelegate.Swift

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    guard let windowScene = (scene as? UIWindowScene) else { return }
    let window = UIWindow(windowScene: windowScene)
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    window.rootViewController = storyboard.instantiateViewController(withIdentifier: "UserViewController") as! UserViewController
    
    self.window = window
    window.makeKeyAndVisible()
}

You can add your condition which view controller scene will dispaly

Celindaceline answered 1/3, 2021 at 18:28 Comment(0)
G
0

Set initial ViewController using Storyboards(instead of Main)

[Swift 5 and Xcode 11]

  1. Main.storyboard -> View Controller -> Attributes Inspector -> Uncheck Is Initial View Controller

  2. App target -> General -> remove all from Main Interface

  3. Edit App delegate

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    
    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        self.window = UIWindow(frame: UIScreen.main.bounds)
        
        let storyboard: UIStoryboard = UIStoryboard(name: "SomeStoryboard", bundle: nil) //SomeStoryboard  is name of .storyboard
        let viewController: ViewController = storyboard.instantiateViewController(withIdentifier: "someStoryboardId") as! ViewController //someStoryboardId is Storyboard ID

        self.window?.rootViewController = viewController
        self.window?.makeKeyAndVisible()

        return true
    }
}
Goldoni answered 22/6, 2021 at 10:12 Comment(0)
C
0

Following code is objective c.

Following code will create your custom entry file without storyboard.

All answers I read on stack overflow have the following code but they are missing important line

MainViewController is the viewController that I want to be the first view controller to be loaded.

- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
    UIWindowScene *winScreen = (UIWindowScene *)scene;
    self.window = [[UIWindow alloc] initWithWindowScene:winScreen];
    
    // Create a root view controller and set it as the root view controller of the navigation controller
    MainViewController *rootViewController = [[MainViewController alloc] init];
    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
    
    // Set the navigation controller as the root view controller of the window
    [self.window setRootViewController:navigationController];
    [self.window makeKeyAndVisible];
}

here I don't know why but each answer does not mention the first line

UIWindowScene *winScreen = (UIWindowScene *)scene;

This code should be added to SceneDelegate.m file Now we could delete main.storyboard file and after deleting this file, we must also delete the two references from info.plist

in project configuration > Info tab > delete Main screen interface file base name
also in project configuration > Info tab > Application scene manifest > Scene configuration > Application session role > Item 0 > delete Storyboard name

Image referring to which reference to delete

Note: This method works now when I am posting this answer but may not work in the future as the new version releases, so keep updating yourself.

Coremaker answered 27/3, 2023 at 13:54 Comment(1)
This does not really answer the question. If you have a different question, you can ask it by clicking Ask Question. To get notified when this question gets new answers, you can follow this question. Once you have enough reputation, you can also add a bounty to draw more attention to this question. - From ReviewStrunk
S
-3

Select the view controller which you want to open first and go to attribute inspector. Go to initial scene and check is initial view controller option.

Now this will be your initial view controller that will open first when application launch.

Satire answered 3/5, 2012 at 9:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.