0

I want to pop current view controller on some condition from appDelegate but I don't know how to do so, if any idea please help me out...................................................................................

import UIKit
import IQKeyboardManagerSwift

let kSharedAppDelegate        = UIApplication.shared.delegate as? AppDelegate
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        self.window = UIWindow(frame: UIScreen.main.bounds)
        IQKeyboardManager.shared.enable = true
        IQKeyboardManager.shared.shouldResignOnTouchOutside = true
        IQKeyboardManager.shared.enableAutoToolbar = false
        //IQKeyboardManager.shared.toolbarTintColor = .white
        //IQKeyboardManager.shared.toolbarBarTintColor = ColorSet.appTheamColor
        kSharedAppDelegate?.moveToSplashVC()
        return true
    }
    

    
    func applicationDidBecomeActive(_ application: UIApplication) {
               // Check we can access the application window
               guard let window = UIApplication.shared.windows.first else {
                   return
               }
               // Check we can access the root viewController
               guard let vc = window.rootViewController else {
                   return
               }
               // Check the root vc is the type that we want to dismiss
               if vc is NoInternetPopUpViewController {
                   vc.dismiss(animated: true, completion: nil)
               }
    }

    
    //MARK:- Show No Internet connection VC
    func showNoInterNetVC() {
        guard  let controller = UIStoryboard(name: Storyboards.kNoInternet, bundle: nil).instantiateViewController(withIdentifier: Identifiers.kNoInternetPopUpViewController) as? NoInternetPopUpViewController else {return}
        
        controller.modalPresentationStyle = .overFullScreen
        controller.modalTransitionStyle = .crossDissolve
        kSharedAppDelegate?.window?.rootViewController?.present(controller, animated: true, completion: nil)
        //window.present(controller , animated: true)
    }
    
    
}
A J
  • 441
  • 4
  • 20
  • Please try this answer: https://stackoverflow.com/questions/51282179/how-to-dismiss-viewcontroller-in-appdelegate – Rushabh Shah Mar 01 '21 at 12:34
  • As Wez says in his answer, "pop" is the opposite of push, and is used with navigation controllers. In your code you have a call to `dismiss(animated:completion:)`, which is used for modals. That is probably what you want. – Duncan C Mar 01 '21 at 12:40

2 Answers2

2

I think pop is the wrong terminology here unless you are using a navigation controller.

If you want to dismiss the currently presented viewController you could check the rootViewController of the applications Window like this.

// Check we can access the application window
guard let window = UIApplication.shared.windows.first else {
    return
}
// Check we can access the root viewController
guard let vc = window.rootViewController else {
    return
}
// Check the root vc is the type that we want to dismiss
if vc is NoInternetPopUpViewController {
    vc.dismiss(animated: true, completion: nil)
}

I also just noticed that you may not need to access the application singleton via the shared property, as applicationDidBecomeActive(_ application: UIApplication) is passing you the Application already - that line would become:

guard let window = application.windows.first else {
Wez
  • 10,555
  • 5
  • 49
  • 63
  • 1
    This is a good, thorough answer. It checks to make sure the top view controller is an instance of `NoInternetPopUpViewController` before dismissing it, which is a good idea. (voted.) – Duncan C Mar 01 '21 at 12:40
  • @AJ let us know what's not working, are you getting any errors? – Wez Mar 01 '21 at 13:15
  • i got the solution but how to match current viewcontroller – A J Mar 01 '21 at 14:12
  • var rootViewController = UIApplication.shared.keyWindow?.rootViewController if (window?.rootViewController?.isKind(of: NoInternetPopUpViewController.self))! { rootViewController?.dismiss(animated: true, completion: nil) } – A J Mar 01 '21 at 14:13
0

There is another way to do this, in newer iOS versions you directly have access to topViewController() so you access it like UIApplication.topViewController() the only downside of it is that you need yo wrap it into an if let statement to check if it is not null. FYI, It won’t be null in most cases if you have let your didFinishLaunching() method run at least once in your app delegate. So that it can stack a view controller to be a top view controller. This won’t be a problem for you since all of the other methods will fail as well if this is the case.

Todo a pop view controller now all you need to do it use top view controller and perform pop on its navigation view controller, or you can dismiss it in case there is no navigation view controller.

Tirth21896
  • 40
  • 10
  • Where is `UIApplication.topViewController()` documented? I can't find a reference to it in Apple's docs. (And BTW, those libraries are part of iOS, not the Swift language. Your statement that "...newer swift versions you directly have access to topViewController()..." is not quite right. The version of iOS and the version of Swift are different things.) – Duncan C Mar 01 '21 at 13:16
  • @DuncanC my apologies for the swift|iOS issue, I should have made that clear. Also, here https://developer.apple.com/documentation/uikit/uinavigationcontroller/1621849-topviewcontroller , a link of the documentation. – Tirth21896 Mar 02 '21 at 05:49