3

i have an app with a signin viewController which modally presents a tabBarController containing several tabs. Each tab has a navigationController and a stack of views. One of those tabs is for settings and has a logout button.

when the user presses the logout button I would like to dismiss all navigation stacks of all tabs and the tabBarController and go back to the initial login viewController. Essentially I want to restore the app to the initial state. Was wondering what the best practice would be to achieve this.

thanks

alionthego
  • 8,508
  • 9
  • 52
  • 125
  • either swap out the key windows root view controller or modally present the login screen on the tab bar controller – DBoyer Aug 23 '15 at 11:45
  • if i modally present the login screen will the navigation controller stacks in the tab bar controller still be kept in memory? thanks. – alionthego Aug 23 '15 at 11:47
  • Yea. If you modally present the login screen it is kind of like the "login later" design where the user can optionally dismiss the login. If you want to force login then I would just swap out the keyWindow's rootViewController. You can animate this transition however you want. – DBoyer Aug 23 '15 at 12:13
  • I'll give it a try. Thanks very much. – alionthego Aug 23 '15 at 12:15
  • If you would like some sample code let me know – DBoyer Aug 23 '15 at 12:21
  • Would be great. Like to see swapping out the key windows root controller. Thx very much. – alionthego Aug 23 '15 at 12:28

3 Answers3

4

If you want to reset all of the tabs and return the apps to it's initial state after logging out, all you have to do is reset the UITabBarController's viewControllers property.

So if you are subclassing UITabBarController the following code should restore your app to its original state.

    self.viewControllers = @[self.viewControllerOne, self.viewControllerTwo, self.viewControllerThree];

From the documentation:

If you change the value of this property at runtime, the tab bar controller removes all of the old view controllers before installing the new ones. The tab bar items for the new view controllers are displayed immediately and are not animated into position.

jstn
  • 1,862
  • 1
  • 13
  • 7
2

This is the code I currently use in the app I am working on to move between the "Login" and "Main UI"

let toViewController = // Login view controller here
let fromView = UIApplication.sharedApplication().keyWindow!.rootViewController!.view
UIApplication.sharedApplication().keyWindow?.rootViewController = toViewController

let toView = toViewController.view
toView.addSubview(fromView)

UIView.animateWithDuration(0.38, delay: 0.2, options: [], animations: {
    fromView?.transform = CGAffineTransformMakeTranslation(-UIScreen.mainScreen().bounds.width, 0)
}) { finished in
    fromView.removeFromSuperview()
}
DBoyer
  • 3,062
  • 4
  • 22
  • 32
0

iOS 11 - Swift 4

Building up on jstn's answer that worked great for me. I've only mapped the VCs to embed them in navigation controllers.

let rootViewController = UIApplication.shared.keyWindow?.rootViewController

guard let tabController = rootViewController as? TabController {
    return
}

//create all your vcs here
// ... 
// ... 

let vcs = [vc1, vc2, vc3, vc4]  

tabController.viewControllers = vcs.map {UINavigationController(rootViewController: $0)}

// Do additional clean up here (i.e. clean cache, UserDefaults, userData objects etc.)
Edouard Barbier
  • 1,815
  • 2
  • 19
  • 32