Perform Segue from App Delegate swift

别等时光非礼了梦想. 提交于 2019-11-28 09:06:38
Lyndsey Scott

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)
sadasd

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)

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

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.

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)

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
}

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)
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!