user3405152
user3405152

Reputation: 187

Perform Segue from App Delegate swift

I need to launch a view controller from the app delegate.

In the way you would perform a segue between view controllers.

I have an if statement that if true needs to show a view controller, this is in the app delegate.

How do I do this from the app delegate?

Upvotes: 18

Views: 17127

Answers (7)

Prashant Sharma
Prashant Sharma

Reputation: 1407

if you want to perform segue from AppDelegate. Implement segue between ViewControllers in your storyboard. Give identifier to your segue.

self.window?.rootViewController!.performSegue(withIdentifier: "your_identifier", sender: nil)

Upvotes: 0

mkul
mkul

Reputation: 810

You don't need to instantiate new ViewController, just perform segue from presentedViewController like this (swift 3.0+)

guard let mainController = self.window?.rootViewController?.presentedViewController as? MainViewController else { return }
mainController.performSegue(withIdentifier: "SEGUE_ID", sender: nil)

In case when your application is based on UITabBarController, you must:

  • fetch UITabBarController
  • select proper controller from viewControllers collection from UITabBarController
  • change index of UITabBarController
  • lastly you can perform segue

Of course you must know the index of your view controller in your UITabBarController

Example code:

guard let tabBarController = self.window?.rootViewController?.presentedViewController as? UITabBarController else { return }
guard let tabBarViewControllers = tabBarController.viewControllers else { return }
guard let mainViewController = tabBarViewControllers[0] as? MainViewController else { return }
tabBarController.selectedIndex = 0
mainViewController(withIdentifier: "SEGUE_ID", sender: nil)

Upvotes: 1

Harshil Kotecha
Harshil Kotecha

Reputation: 2896

If you want segue in App Delegate Swift 3.0

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

        if UserDefaults.standard.bool(forKey: PARAM.STATUS) {
            DispatchQueue.main.async {
                self.window?.rootViewController?.performSegue(withIdentifier: PARAM.SEGUETOHOME, sender: nil)
            }

        }
        // Override point for customization after application launch.
        return true
    }

Note if you not use DispatchQueue.main.async than your segue is not perform

Upvotes: 3

sadasd
sadasd

Reputation: 111

if you want to use segue identifier, you can use in Swift 2.2.

self.window?.rootViewController!.performSegueWithIdentifier("YOUR SEGUE IDENTIFIER", sender: nil)

and for Swift 3.1 :

self.window?.rootViewController!.performSegue(withIdentifier: "YOUR SEGUE IDENTIFIER", sender: nil)

Upvotes: 11

Lyndsey Scott
Lyndsey Scott

Reputation: 37300

c_rath's answer is mostly right, but you don't need to make the view controller a root view controller. You can in fact trigger a segue between the top view on the navigation stack and any other view controller, even from the App Delegate. For example, to push a storyboard view controller, you could do this:

Swift 3.0 and Later

// Access the storyboard and fetch an instance of the view controller
let storyboard = UIStoryboard(name: "Main", bundle: nil);
let viewController: MainViewController = storyboard.instantiateViewController(withIdentifier: "ViewController") as! MainViewController;

// Then push that view controller onto the navigation stack
let rootViewController = self.window!.rootViewController as! UINavigationController;
rootViewController.pushViewController(viewController, animated: true);

Swift 2.0 and Earlier

// Access the storyboard and fetch an instance of the view controller
var storyboard = UIStoryboard(name: "Main", bundle: nil)
var viewController: MainViewController = storyboard.instantiateViewControllerWithIdentifier("ViewController") as MainViewController

// Then push that view controller onto the navigation stack
var rootViewController = self.window!.rootViewController as UINavigationController
rootViewController.pushViewController(viewController, animated: true)

Upvotes: 41

Sakiboy
Sakiboy

Reputation: 7459

Here's what you'd do if your rootViewController did NOT inherit from UINavigationViewController:

Basically you check what the currently presented tab is and then push from THAT view controller, rather than the rootViewController that inherits from UITabBarController.

        let root = self.window?.rootViewController as UITabBarController

        switch(root.selectedIndex){
        case 0:
            root.viewControllers?[0].pushViewController(viewController, animated: true)
            break;
        case 1:
            root.viewControllers?[1].pushViewController(viewController, animated: true)
            break
        default:
            println("Error presenting ViewController")
            break;
        }

My application has an initial/rootViewController that inherits from UITabBarController, each of it's UITabBar Relationship Controllers inherit from UINavigationController, allowing me to pushViewController from them.

Upvotes: 2

c_rath
c_rath

Reputation: 3628

You can't actually perform a segue from the AppDelegate since a segue is a transition from one scene to another. One thing you can do however is instantiate a new view controller and present it from the AppDelegate. Something similar to the following should work...

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    // Override point for customization after application launch.
    var storyboard = UIStoryboard(name: "Main", bundle: nil)
    var viewController: MasterViewController = storyboard.instantiateViewControllerWithIdentifier("viewController") as MasterViewController

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

    return true
}

Upvotes: 2

Related Questions