Get current view controller from the app delegate (modal is possible)
I suggest you use NSNofiticationCenter.
//in AppDelegate:
@interface AppDelegate()
{
...
id lastViewController;
...
}
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleCurrentViewController) name:@"CurrentViewController" object:nil];
...
}
- (void)handleCurrentViewController:(NSNotification *)notification {
if([[notification userInfo] objectForKey:@"lastViewController"]) {
lastViewController = [[notification userInfo] objectForKey:@"lastViewController"];
}
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
NSLog(@"last view controller is %@", [(UIViewController *)lastViewController class]);
}
@end
//in every ViewController you want to detect
@implementation SomeViewController
...
- (void) viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] postNotificationName:@"CurrentViewController" object:nil userInfo:[NSDictionary dictionaryWithObjectsAndKeys:self, @"lastViewController", nil]];
}
...
@end
Present view controller from app delegate
You can also try:
[[[UIApplication sharedApplication] keyWindow] rootViewController]
How I use it:
#define ROOTVIEW [[[UIApplication sharedApplication] keyWindow] rootViewController]
[ROOTVIEW presentViewController:interstitialViewController animated:YES completion:^{}];
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
Objective-C : present view controller from App Delegate above everything
Try this one:
+ (UIViewController*) topMostController {
UIViewController *topController = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
while (topController.presentedViewController) {
topController = topController.presentedViewController;
}
return topController;
}
With this method you can find the currently active view controller.
Good Luck
Display modal view controller from AppDelegate every time app is opened
1- Regarding how to know the index you can cast the rootVC as a tabBarController and ask it for the current index (selectedIndex
) like this
let currentIndex = rootTab.selectedIndex
2- You can get rootVC as
if let rootTab = window?.rootViewController as? UITabBarController
you can show it when app becomes active ( in applicationDidBecomeActive
) delegate method
to get the VC
let vc = rootTab.viewControllers[rootTab.selectedIndex]
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];
}
Calling method in current view controller from App Delegate in iOS
To do the refresh of the view do not call viewWillAppear
if the view is already displayed. What you want to do is the following:
When ConnectionDidFinishLoading
method is triggered post a notification
[[NSNotificationCenter defaultCenter] postNotificationName:@"refreshView" object:nil];
In your viewController
observe for this notification. You do it by adding this code to your init or viewDidLoad
method
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshView:) name:@"refreshView" object:nil];
Now implement -(void)refreshView:(NSNotification *) notification
method in your viewController
to manage your view to your liking.
Get the current displaying UIViewController on the screen in AppDelegate.m
You can use the rootViewController
also when your controller is not a UINavigationController
:
UIViewController *vc = self.window.rootViewController;
Once you know the root view controller, then it depends on how you have built your UI, but you can possibly find out a way to navigate through the controllers hierarchy.
If you give some more details about the way you defined your app, then I might give some more hint.
EDIT:
If you want the topmost view (not view controller), you could check
[[[[UIApplication sharedApplication] keyWindow] subviews] lastObject];
although this view might be invisible or even covered by some of its subviews...
again, it depends on your UI, but this might help...
Related Topics
Difference Between Completion Handler and Blocks:[Ios]
How to Have a Uiscrollview Scroll and Have a Gesture Recognizer
How to Insert Cell in Uicollectionview Programmatically
How to Hide the Tabbar When Navigate with Navigationlink in Swiftui
New Itunes User Interface Unable to Find "Ready to Upload Binary"
Uialertview in Swift, Getting Exc_Bad_Access
Swiftui - How to Get Didset to Fire When Changing a @Published Struct
Using Apple's Reachability to Check Remote Server Reachability in Swift
Property "Assign" and "Retain" for Delegate
What Is Main Thread Checker in Xcode
How to Keep the Keyboard from Covering My UI Instead of Resizing It
Nw_Host_Stats_Add_Src Recv Too Small, Received 24, Expected 28
Where to Set Environment Variables for App
Swiftui Buttonstyle - How to Check If Button Is Disabled or Enabled