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?
5 Answers
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];
}

- 4,765
- 2
- 23
- 25
-
1This 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
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];

- 931
- 1
- 10
- 36
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)
}
}
}

- 267
- 3
- 8
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.

- 21
- 3
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()

- 13
- 6