3

I have a tab bar app with navigation controllers on 4 out of the 5 tabs on the app. I have a 'reset app' function within my app which clears all data etc... and I would also like that to pop all of the view controllers back to their top view. I know how to pop to root using popToRootViewControllerAnimated for a single nav controller but is it possible to pop all of the view controllers on each tab?

Carl
  • 841
  • 1
  • 13
  • 33

5 Answers5

11

You need to enumerate through viewControllers array of tabBarController & pop to root view controller if controller in array is UINavigationController like-

for(UIViewController *viewController in tabBarController.viewControllers)
{
    if([viewController isKindOfClass:[UINavigationController class]])
       [(UINavigationController *)viewController popToRootViewControllerAnimated:NO];
}
Rahul Wakade
  • 4,765
  • 2
  • 23
  • 25
  • 1
    This works though Im getting 'Unbalanced calls to begin/end appearance transitions for' - any idea to fix it? – Teffi Jan 11 '17 at 06:14
  • Is there a chance that you are trying to push/pop multiple view controllers on a navigation controller at the same time? http://stackoverflow.com/questions/9088465/unbalanced-calls-to-begin-end-appearance-transitions-for-detailviewcontroller might help you. – Rahul Wakade Jan 11 '17 at 08:11
1

Rahul's answer is perfect solution. But if there are more than 5 tabs in your tabbar then you will see the "more" tab. you will need to reset this tab explicitly (just pop tabBarController.moreNavigationController to rootViewController).

here is code example:

for(UIViewController *viewController in tabBarController.viewControllers)
{
    if([viewController isKindOfClass:[UINavigationController class]])
       [(UINavigationController *)viewController popToRootViewControllerAnimated:NO];
}
[tabBarController.moreNavigationController popToRootViewControllerAnimated:NO];

..

W.S
  • 931
  • 1
  • 10
  • 36
1

Here's Swift 5 for anyone that needs it:

if let tabVcs = navigationController?.tabBarController?.viewControllers {
        for vc in tabVcs {
            if let navVc = vc as? UINavigationController {
                navVc.popToRootViewController(animated: false)
            }
        }
    }
joe
  • 267
  • 3
  • 8
0

Another option you have is to use NSNotifications. I needed to trigger a popToRootViewController on all of my tabs when closing a modal view (slide show on timer) and this is the only way I could figure out how to do it. I triggered the NSNotification in viewWillDissapear method of modal view and then responded to it in each view I wished to close.

Bean
  • 21
  • 3
0
func popAll(){

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

    if let tabBarViewControllers = tabBarController.viewControllers {


    let campusController = tabBarViewControllers[0] as! UINavigationController

    let campusTVC = campusController.viewControllers[0] as! CampusTVC

    _ = campusTVC.navigationController?.popToRootViewController(animated: false)

    let adController = tabBarViewControllers[1] as! UINavigationController

    let adminTVC = adminController.viewControllers[0] as! AdTVC

    _ = adminTVC.navigationController?.popToRootViewController(animated: false)

    let searchController = tabBarViewControllers[2] as! UINavigationController

    let searchTVC = searchController.viewControllers[0] as! SearchTVC
    _ = searchTVC.navigationController?.popToRootViewController(animated: false)


    } 

}

Example of my code popping all tabs in Swift. This is in my App Delegate. This is how I call it in my VC

let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.popAll()