How to get visible viewController from app delegate when using storyboard?
This should do it for you:
- (void)applicationWillResignActive:(UIApplication *)application
{
UIViewController *vc = [self visibleViewController:[UIApplication sharedApplication].keyWindow.rootViewController];
}
- (UIViewController *)visibleViewController:(UIViewController *)rootViewController
{
if (rootViewController.presentedViewController == nil)
{
return rootViewController;
}
if ([rootViewController.presentedViewController isKindOfClass:[UINavigationController class]])
{
UINavigationController *navigationController = (UINavigationController *)rootViewController.presentedViewController;
UIViewController *lastViewController = [[navigationController viewControllers] lastObject];
return [self visibleViewController:lastViewController];
}
if ([rootViewController.presentedViewController isKindOfClass:[UITabBarController class]])
{
UITabBarController *tabBarController = (UITabBarController *)rootViewController.presentedViewController;
UIViewController *selectedViewController = tabBarController.selectedViewController;
return [self visibleViewController:selectedViewController];
}
UIViewController *presentedViewController = (UIViewController *)rootViewController.presentedViewController;
return [self visibleViewController:presentedViewController];
}
Opening view controller from app delegate using swift
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
How to check in AppDelegate if a particular ViewController is currently open
By initiating messagesVC
, you're creating a brand new UserMessageViewController
that won't have been presented yet. The particular instance of the controller you want will already be instantiated, so you must find it using the view controller hierarchy.
The AppDelegate
gives you access to the rootViewController
of your application which will be the very first controller you have in your storyboard. From this controller, you can make your way through the child view controllers in search of a UserMessageViewController
.
Here is an extension that will start at the rootViewController
and bubble its way up until it reaches the top of the view controller hierarchy stack.
extension UIApplication {
func topViewController(_ base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
switch (base) {
case let controller as UINavigationController:
return topViewController(controller.visibleViewController)
case let controller as UITabBarController:
return controller.selectedViewController.flatMap { topViewController($0) } ?? base
default:
return base?.presentedViewController.flatMap { topViewController($0) } ?? base
}
}
}
Create a new file called UIApplication+TopViewController.swift
and paste in the above extension. Then inside AppDelegate
, you will be able to get the current view controller that is being presented using UIApplication.shared.topViewController()
:
if let messagesVC = UIApplication.shared.topViewController() as? UserMessageViewController {
print("Messages viewcontroller is visible and open")
} else {
print("Messages viewcontroller isnt visible and not open")
}
By casting the top view controller to UserMessageViewController
, we can determine whether or not the notification should be presented.
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
}
How to push a view controller from App Delegate on didReceiveRemoteNotification in Swift?
I managed to get it working as I needed with help from both Sh_Khan and the answer I found in this thread: How can I show ViewController in UITabBarController?
My initial view controller is a tabBar and therefore, this is the correct code for me:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
let info = userInfo as NSDictionary
let name: String = info.value(forKey: "view-controller") as! String
switch name {
case "controller1":
let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
let controller1VC = storyboard.instantiateViewController(withIdentifier: "controller1VC") as! Controller1VC
let tabBar = self.window?.rootViewController as? UITabBarController
let nav = tabBar?.selectedViewController as? UINavigationController
nav?.pushViewController(controller1VC, animated: true)
default:
print("Nothing")
}
}
So this code will essentially convert the tabBar
to a UINavigationController
allowing for a pushViewController
to work.
I hope this helps anyone else.
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.
View controller added in app delegate not appearing
You can do it like that:
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if Settings.appSettings.authToken != nil {
self.showMainController()
}
NotificationCenter.default.addObserver(forName: .authorizationOperationDidSuccess,
object: nil, queue: nil) { (notification) in
self.showMainController()
}
return true
}
private func showMainController() {
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let controller: UIViewController =
storyBoard.instantiateViewController(withIdentifier: "Main") as UIViewController
if self.window == nil {
self.window = UIWindow(frame: UIScreen.main.bounds)
}
self.window?.backgroundColor = UIColor.white
self.window?.rootViewController = controller
self.window?.makeKeyAndVisible()
}
private func showAuthorizationController() {
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let controller: UIViewController =
storyBoard.instantiateViewController(withIdentifier: "Auth") as UIViewController
if self.window == nil {
self.window = UIWindow(frame: UIScreen.main.bounds)
}
self.window?.backgroundColor = UIColor.white
self.window?.rootViewController = controller
self.window?.makeKeyAndVisible()
}
On successful login make
NotificationCenter.default.post(name: .authorizationOperationDidSuccess,
object: nil)
How to get root view controller?
if you are trying to access the rootViewController
you set in your appDelegate. try this:
Objective-C
YourViewController *rootController = (YourViewController*)[[(YourAppDelegate*)
[[UIApplication sharedApplication]delegate] window] rootViewController];
Swift
let appDelegate = UIApplication.sharedApplication().delegate as AppDelegate
let viewController = appDelegate.window!.rootViewController as YourViewController
Swift 3
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let viewController = appDelegate.window!.rootViewController as! YourViewController
Swift 4 & 4.2
let viewController = UIApplication.shared.keyWindow!.rootViewController as! YourViewController
Swift 5 & 5.1 & 5.2
let viewController = UIApplication.shared.windows.first!.rootViewController as! YourViewController
Related Topics
How to Do Transforms on a Calayer
How to Debug "Invalid Bundle" Error Which Happens Only After Submitting to App Store
Uiview Atop the Keyboard Similar to Imessage App
Storyboard Segue from View Controller to Itself
iOS Steps to Create Custom Uitableviewcell with Xib File
iOS 9.3:An Ssl Error Has Occurred and a Secure Connection to the Server Cannot Be Made
How to Add My App to the Share Sheet Action
Calling Uiviewcontroller Method from App Delegate
How to Detect Call Incoming Programmatically
How to Check If iOS App Is in Background
Multiline Uilabel with Adjustsfontsizetofitwidth
Dynamic Uiimageview Size Within Uitableview
"Interfaceorientation" Is Deprecated in iOS 8, How to Change This Method Objective C
How to Get Uiviewcontroller of a Uiview's Superview in iOS
Run Repeating Nstimer with Gcd
Sudzc Arc Version - Objc_Msgsend Call Causes Exc_Bad_Access Using 64-Bit Architecture