Reputation: 1118
I am trying to create a push notification which determines which view to open according to information obtained from the push.
I have managed to get the information from the push, but I am now struggling to get the view to open
Looking at other stack overflow questions I have the following currently:
App Delegate Did finish loading:
//Extract the notification data
if let notificationPayload = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? NSDictionary {
// Get which page to open
let viewload = notificationPayload["view"] as? NSString
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
//Load correct view
if viewload == "circles" {
var viewController = self.window?.rootViewController?.storyboard?.instantiateViewControllerWithIdentifier("Circles") as! UIViewController
self.window?.rootViewController = viewController
}
}
Currently this is failing on the var ViewController = self... line.
Upvotes: 81
Views: 115925
Reputation: 39
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
self.window = UIWindow(windowScene: windowScene)
let mainStoryboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc : UIViewController = mainStoryboard.instantiateViewController(withIdentifier: "LoginViewController")
let rootNC = UINavigationController(rootViewController: vc)
self.window?.rootViewController = rootNC
self.window?.makeKeyAndVisible()
}
Upvotes: -1
Reputation: 23407
You have to set ViewController StoryBoardId property as below image.
open viewController using coding as below in swift
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let mainStoryboardIpad : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewControlleripad : UIViewController = mainStoryboardIpad.instantiateViewControllerWithIdentifier("Circles") as UIViewController
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.rootViewController = initialViewControlleripad
self.window?.makeKeyAndVisible()
return true
}
For iOS 13+ (based on an article by dev2qa)
Open SceneDelegate.swift
and add following
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// If this scene's self.window is nil then set a new UIWindow object to it.
self.window = self.window ?? UIWindow()
// Set this scene's window's background color.
self.window!.backgroundColor = UIColor.red
// Create a ViewController object and set it as the scene's window's root view controller.
self.window!.rootViewController = ViewController()
// Make this scene's window be visible.
self.window!.makeKeyAndVisible()
guard scene is UIWindowScene else { return }
}
There is an open-source navigation utility which attempts to make this easier. Example
Upvotes: 119
Reputation: 1448
In Swift 3
let mainStoryboard : UIStoryboard = UIStoryboard(name: StorybordName, bundle: nil)
let initialViewControlleripad : UIViewController = mainStoryboard.instantiateViewController(withIdentifier: identifierName) as UIViewController
if let navigationController = self.window?.rootViewController as? UINavigationController
{
navigationController.pushViewController(initialViewControlleripad, animated: animation)
}
else
{
print("Navigation Controller not Found")
}
Upvotes: 5
Reputation: 1559
SWIFT 4
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let destinationViewController = storyboard.instantiateViewController(withIdentifier: "LandVC") as! LandingPageVC
destinationViewController.webpageURL = NotificationAdvertisement._htmlpackagePath
destinationViewController.adID = NotificationAdvertisement._adID
destinationViewController.toneID = NotificationAdvertisement.toneID
let navigationController = self.window?.rootViewController as! UIViewController
navigationController.showDetailViewController(destinationViewController, sender: Any?.self)
Upvotes: 0
Reputation: 1868
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions:
[UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let mainStoryboardIpad : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewControlleripad : UIViewController = mainStoryboardIpad.instantiateViewController(withIdentifier: "Circles") as UIViewController
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.rootViewController = initialViewControlleripad
self.window?.makeKeyAndVisible()
return true}
Upvotes: 6
Reputation: 31
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let destinationViewController = storyboard.instantiateViewController(withIdentifier: "LandVC") as! LandingPageVC
destinationViewController.webpageURL = NotificationAdvertisement._htmlpackagePath
destinationViewController.adID = NotificationAdvertisement._adID
destinationViewController.toneID = NotificationAdvertisement.toneID
let navigationController = self.window?.rootViewController as! UIViewController
navigationController.showDetailViewController(destinationViewController, sender: Any?.self)
Upvotes: 1
Reputation: 272
Swift 3 SWRevealViewController
self.window = UIWindow(frame: UIScreen.main.bounds)
let storyBoard = UIStoryboard(name: "Main", bundle: nil)
let viewController = storyBoard.instantiateViewController(withIdentifier: "SWRevealViewController") as! SWRevealViewController
self.window?.rootViewController = viewController
self.window?.makeKeyAndVisible()
Upvotes: 3
Reputation: 3205
First Initialize the window
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
let storyBoard = UIStoryboard(name: "Main", bundle: nil)
For setting rootViewController
inside AppDelegate
Class
let viewController = storyBoard.instantiateViewControllerWithIdentifier("Circles") as UIViewController
self.window?.rootViewController = viewController
self.window?.makeKeyAndVisible()
Upvotes: 8
Reputation: 520
Swift 3
To present the view together with the navigation controller:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier :"InboxViewController") as! InboxViewController
let navController = UINavigationController.init(rootViewController: viewController)
if let window = self.window, let rootViewController = window.rootViewController {
var currentController = rootViewController
while let presentedController = currentController.presentedViewController {
currentController = presentedController
}
currentController.present(navController, animated: true, completion: nil)
}
Upvotes: 14
Reputation: 31
I'd say creating UIWindow each time you want to change rootViewController is bad idea. After couple changes of rootVC (using upper solution) you are gonna have many UIWindows in your app at one time.
In my opinion better solution is:
let rootVC = UIStoryboard(name: "StoryboardName", bundle: nil).instantiateViewControllerWithIdentifier("newRootVCIdentifier") as UIViewController
rootVC.view.frame = UIScreen.mainScreen().bounds
UIView.transitionWithView(self.window!, duration: 0.5, options: .TransitionCrossDissolve, animations: {
self.window!.rootViewController = rootVC
}, completion: nil)
Done!
You don't need method window?.makeKeyAndVisible()
, cause this solution works on current app window.
Upvotes: 3
Reputation: 689
Swift 3:
This is my preferred approach when presenting a new viewController from the current viewController through the AppDelegate. This way you don't have to completely tear down your view hierarchy when handling a push notification or universal link
if let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "someController") as? SomeController {
if let window = self.window, let rootViewController = window.rootViewController {
var currentController = rootViewController
while let presentedController = currentController.presentedViewController {
currentController = presentedController
}
currentController.present(controller, animated: true, completion: nil)
}
}
Upvotes: 56