Set Initial Viewcontroller in Appdelegate - Swift

set initial viewcontroller in appdelegate - swift

Xcode11 and SceneDelegate note:

Starting from Xcode11, because of SceneDelegates, it's likely that you shouldn't do it inside AppDelegate. Instead do it from SceneDelegate. For more on that see this other answer



Old answer:

I used this thread to help me convert the objective C to swift, and its working perfectly.

Instantiate and Present a viewController in Swift

Swift 2 code:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)

let storyboard = UIStoryboard(name: "Main", bundle: nil)

let initialViewController = storyboard.instantiateViewControllerWithIdentifier("LoginSignupVC")

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

return true
}

Swift 3 code:

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

let storyboard = UIStoryboard(name: "Main", bundle: nil)

let initialViewController = storyboard.instantiateViewController(withIdentifier: "LoginSignupVC")

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

return true
}

Setting Initial View Controller Programmatically Swift

To do it in the view controller and not in the app delegate: Just fetch the reference to the AppDelegate in your view controller and reset it's window object with the right view controller as it's rootviewController.

Step 1: Make some NSUserDefaults the user can adjust. A couple of buttons, some switches in a table view, something. Then when the user taps the button, we change the NSUserDefault.

@IBAction func SwitchLaunchViewtoViewController2(sender: AnyObject) {
defaults.setObject("ViewController2", forKey: "LaunchView")
}
@IBAction func SwitchLaunchViewtoViewController1(sender: AnyObject) {
defaults.setObject("ViewController1", forKey: "LaunchView")
}

Hook a couple of buttons in a settings view controller up to these functions, and we've started.

Step 2: Set up Storyboard IDs for all the storyboards you want to be able to be set as the launch view. So, for each View Controller that could be an initial view controller:

-Head into your storyboard.

-Click on the view controller.

-In the sidebar at right, click on the newspaper-like icon, which you control the class in.

-In the "Identity" section (third row), check "Use Storyboard ID" (make sure it's on) and then type in something like "VC1" in the "Storyboard ID" text field. Make sure you choose a different Storyboard ID for each view controller.

-Repeat for each view controller.

Step 3: Set up your initial view controller in the AppDelegate.swift file. Head into the func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool section of your app delegate.

Add this to read from the NSUserDefault you created earlier:

let defaults = NSUserDefaults.standardUserDefaults()
if let launchview = defaults.stringForKey("LaunchView")
{

}

This looks for an NSUserDefault string called "LaunchView" (which you created in step 1) and sets it to the new variable launchview if it finds a matching NSUserDefault.

Then, inside the if let launchview... brackets, we want to check what you set your LaunchView to. For every object you set to LaunchView in step 1 (in the example, I did "ViewController2" and "ViewController1"), you have to check for it here. So, inside those brackets, we add this:

if launchview == "ViewController2" {

} else if launchview == "ViewController1" {

}

Then, inside each of those if statements, we add the following code:

let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.window = UIWindow(frame: UIScreen.mainScreen().bounds)
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil) // this assumes your storyboard is titled "Main.storyboard"
let yourVC = mainStoryboard.instantiateViewControllerWithIdentifier("YOUR_VC_IDENTIFIER") as! YourViewController // inside "YOUR_VC_IDENTIFIER" substitute the Storyboard ID you created in step 2 for the view controller you want to open here. And substitute YourViewController with the name of your view controller, like, for example, ViewController2.
appDelegate.window?.rootViewController = yourVC
appDelegate.window?.makeKeyAndVisible()

This will open the chosen window when your application finishes loading after it's been in the background a while.

Your finished didFinishLoadingWithOptions section of your AppDelegate might look something like this:
(don't just copy and paste, read the instructions above)

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

let defaults = NSUserDefaults.standardUserDefaults()
if let launchview = defaults.stringForKey("LaunchView")
{

if launchview == "ViewController1" {

let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.window = UIWindow(frame: UIScreen.mainScreen().bounds)
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let yourVC = mainStoryboard.instantiateViewControllerWithIdentifier("VC1") as! ViewController1
appDelegate.window?.rootViewController = yourVC
appDelegate.window?.makeKeyAndVisible()

} else if launchview == "ViewController2" {
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.window = UIWindow(frame: UIScreen.mainScreen().bounds)
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let yourVC = mainStoryboard.instantiateViewControllerWithIdentifier("VC1") as! ViewController1
appDelegate.window?.rootViewController = yourVC
appDelegate.window?.makeKeyAndVisible()
}

}

return true
}

I hope this helps you, and many thanks to Ankit Goel who helped me with this one so much. Read the comments down below for more.

One final note: if you are using switches in a settings view, make sure on the viewDidLoad of that settings view controller you read from the NSUserDefault LaunchView which one the user selected last.

How to set the Initial viewController in AppDelegate Programatically?

1) Open your AppDelegate.swift and add property

var window: UIWindow?

2) In

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool

a) initialize this window:

window = UIWindow(frame: UIScreen.main.bounds)

b) set UIViewController you needed to window's rootViewController property:

window?.rootViewController = myViewController

c) make this window key and visible:

window?.makeKeyAndVisible()

That is all.
And don't forget to remove your storyboard from target settings:
Remove storyboard from target

Hope its help.

IOS | Unable to change root view controller in app delegate

If you are targeting only iOS 13+, the only change you should need to make is to add one line:

    window?.rootViewController = initialViewController

// add this line
self.window = window

window?.makeKeyAndVisible()

If you want to support earlier iOS versions, here is a complete SceneDelegate / AppDelegate implementation:

SceneDelegate.swift

//
// SceneDelegate.swift
// Created by Don Mag on 3/27/20.
//

import UIKit

// entire class is iOS 13+
@available(iOS 13.0, *)
class SceneDelegate: UIResponder, UIWindowSceneDelegate {

var window: UIWindow?

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

print("Scene Delegate willConnectTo", UserDefaults.standard.bool(forKey: "isLoggedIn"))

guard let windowScene = (scene as? UIWindowScene) else { return }
let window = UIWindow(frame: windowScene.coordinateSpace.bounds)
window.windowScene = windowScene

if UserDefaults.standard.bool(forKey: "isLoggedIn") {
guard let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "HomeVC") as? TabController else {
fatalError("Could not instantiate HomeVC!")
}
window.rootViewController = vc
} else {
guard let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "AuthVC") as? AuthViewController else {
fatalError("Could not instantiate HomeVC!")
}
window.rootViewController = vc
}

self.window = window

window.makeKeyAndVisible()
}

}

AppDelegate.swift

//
// AppDelegate.swift
// Created by Don Mag on 3/27/20.
//

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

var window : UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]?) -> Bool {
if #available(iOS 13, *) {
// do only pure app launch stuff, not interface stuff
} else {

print("App Delegate didFinishLaunching... isLoggedIn:", UserDefaults.standard.bool(forKey: "isLoggedIn"))

self.window = UIWindow()

if UserDefaults.standard.bool(forKey: "isLoggedIn") {
guard let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "HomeVC") as? TabController else {
fatalError("Could not instantiate HomeVC!")
}
window?.rootViewController = vc
} else {
guard let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "AuthVC") as? AuthViewController else {
fatalError("Could not instantiate HomeVC!")
}
window?.rootViewController = vc
}

window?.makeKeyAndVisible()

}
return true
}

// MARK: UISceneSession Lifecycle

// iOS 13+ only
@available(iOS 13.0, *)
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
// iOS 13+ only
@available(iOS 13.0, *)
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
}

}

Set rootViewController programmatically not working, picking initial view controller from storyboard only in Xcode 11

Got the answer by doing some more google, i mean stackoverflow.

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

var window: UIWindow?
let storyboard = UIStoryboard(name: "Main", bundle: nil)

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = scene as? UIWindowScene else { return }
let vc = storyboard.instantiateViewController (withIdentifier: "Primary") as! ViewController
window = UIWindow(windowScene: windowScene)
window?.rootViewController = vc
window?.makeKeyAndVisible()
}

SceneDelegate is used for this purpose since iOS 13 not AppDelegate. Here is the link SceneDelegate example



Related Topics



Leave a reply



Submit