Reputation:
I want to go to the current opened view controller after the user authenticates with the passcode.
this is my code on (EnterForeground) in appDelegate:
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
let stb = UIStoryboard(name: "Main", bundle: nil)
let ps = stb.instantiateViewController(withIdentifier: "psID") as! PassC_VC
let appdelegate = UIApplication.shared.delegate as! AppDelegate
self.window?.makeKeyAndVisible()
DispatchQueue.global().async {
DispatchQueue.main.async {
ps.modalPresentationStyle = UIModalPresentationStyle.currentContext
appdelegate.window?.rootViewController = ps
print("in forground")
}
}
}
this code working successfully and show this window but the problem to dismissing this controller and show the currently active view controller that was opened before show passcode View Controller.
this is my PassC_VC.swift code: addition information: I'm not using any UINavigationController or something
on OK button click after entering password
self.dismiss(animated: true, completion: nil)
Upvotes: 1
Views: 1988
Reputation: 521
You can only dismiss controllers you present. You did not present "ps", instead you set is as the window rootViewController. This means that is is the first controller in the screen, so dismissing it doesn't make sense.
To go back to the controller you had before on screen, you could do one of the following:
OPTION 1: VIEW CONTROLLER REFERENCE
hold a reference to that controller in the appDelegate when your app enters foregound:
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
let stb = UIStoryboard(name: "Main", bundle: nil)
let ps = stb.instantiateViewController(withIdentifier: "psID") as! PassC_VC
let appdelegate = UIApplication.shared.delegate as! AppDelegate
self.window?.makeKeyAndVisible()
DispatchQueue.global().async {
DispatchQueue.main.async {
ps.modalPresentationStyle = UIModalPresentationStyle.currentContext
if let delegate = UIApplication.shared.delegate as? AppDelegate {
//Storing the reference
delegate.yourReferenceToPreviousController = delegate.window?.rootViewController
//Assigning the new controller
delegate.window?.rootViewController = ps
print("in forground")
}
}
}
}
and , on "OK button click after entering password" doing:
if let delegate = UIApplication.shared.delegate as? AppDelegate {
//You can now use your stored reference to reassign the root view controller
delegate.window?.rootViewController = delegate.yourReferenceToPreviousController
}
OPTION 2: RE-PRESENTING THE PREVIOUS VIEW CONTROLLER
Or you could avoid keeping a reference to the previous controller and re-instantiate it by doing, on "OK button click after entering password":
let previousController = PreviousController() //This is in code but you can initialize it via storyboard
self.present(previousController, animated: true)
OPTION 3: PROPERLY PRESENT/DISMISS YOUR VIEW CONTROLLER
Another approach would be changing the way you show the controller, by actually getting the visibleController and making him present the PassCode controller like this:
You can use this extension to get the visible controller:
extension UIWindow {
func visibleViewController() -> UIViewController? {
if let rootViewController: UIViewController = self.rootViewController {
return UIWindow.getVisibleViewControllerFrom(vc: rootViewController)
}
return nil
}
private class func getVisibleViewControllerFrom(vc:UIViewController) -> UIViewController {
if vc.isKind(of: UINavigationController.self) {
let navigationController = vc as? UINavigationController
return UIWindow.getVisibleViewControllerFrom(vc: navigationController!.visibleViewController!)
} else if vc.isKind(of: UITabBarController.self) {
let tabBarController = vc as? UITabBarController
return UIWindow.getVisibleViewControllerFrom(vc: tabBarController!.selectedViewController!)
} else {
if let presentedViewController = vc.presentedViewController {
return UIWindow.getVisibleViewControllerFrom(vc: presentedViewController)
} else {
return vc
}
}
}
}
Then in the applicationWillEnterForegound:
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
let stb = UIStoryboard(name: "Main", bundle: nil)
let ps = stb.instantiateViewController(withIdentifier: "psID") as! PassC_VC
let appdelegate = UIApplication.shared.delegate as! AppDelegate
self.window?.makeKeyAndVisible()
DispatchQueue.global().async {
DispatchQueue.main.async {
ps.modalPresentationStyle = UIModalPresentationStyle.currentContext
//You get the controller that is on screen
let visibleViewController = UIWindow.getVisibleViewControllerFrom(vc: window?.rootViewController!)
//Then make it present the controller you want
visibleViewController.present(ps, animated: true)
print("in forground")
}
}
}
This way you are actually presenting the controller so you can:
self.dismiss(animated: true, completion: nil)
Like you wanted to.
Hope it helps.
Upvotes: 1