Tom Moore
Tom Moore

Reputation: 47

Swift - dismiss a view controller on another tab bar item

I have a tab bar application that has some show segue's in each tab. I would like to be able to dismiss the view controllers from one tab bar from an action in another tab bar.

In my example, when a user taps log-out, I want to dismiss all the presented view controllers in each of the tabs.

The tab bar controller is the root view controller:

let tabBarController = self.window!.rootViewController as? UITabBarController

I'm not sure where I'm going wrong as many of the following code snippets that I have tried do not work for me...

    self.navigationController?.popToRootViewController(animated: true)

    self.view.window?.rootViewController?.dismiss(animated: false, completion: nil) //doesn't dismiss presented VC's on other tab bar controller

    UIApplication.shared.keyWindow?.rootViewController?.dismiss(animated: false, completion: nil)

self.view.window?.rootViewController?.dismiss(animated: true, completion: nil)

dismissViewControllers()

dismiss(animated: false, completion: nil)

}

func dismissViewControllers() {

    guard let vc = self.presentingViewController else { return }

    while (vc.presentingViewController != nil) {
        vc.dismiss(animated: true, completion: nil)
    }
}

The presented view controllers are still on the stack. Is there anything obvious that I am missing here?

Upvotes: 0

Views: 1514

Answers (1)

nayem
nayem

Reputation: 7585

The thing you'll be needing for this to achieve is How to reset root view controller at the time of selecting the tab item of log-out. To know which item has been selected in the UITabBarController you will need to Detect when a tab bar item is pressed.


Theory/Pseudocode:

By composing the above points, here is a theoretical example:

class SpecialTabBarController: UITabBarController, UITabBarControllerDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()
        delegate = self
    }

    func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
        if let _ = viewController as? LogoutViewController {
            // Reset root view controller of the UIWindow
            // And must call makeKeyAndVisible() on the UIWindow object
        }
    }
}

By the way, don't forget to set this SpecialTabBarController as the custom class of your Tab Bar Controller if used from the Interface Builder.


Bonus:

Here is a complete solution that you can check though there are more considerations made in the SpecialTabBarController because of the Difference between SceneDelegate and AppDelegate introduced in iOS 13.

Upvotes: 1

Related Questions