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?
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)
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.asyncthan 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
viewControllerscollection fromUITabBarController - 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)
来源:https://stackoverflow.com/questions/27135997/perform-segue-from-app-delegate-swift