1

I have a problem with changing root in my app.

enter image description here

Design of my app. After I login into app I would like to change root vc to UITabBarViewController to clean a stack.

I've faced multiple problems.

  1. Setting vc to tab bar on apply login action -> or in bottom vc:

    self.performSegue(withIdentifier: "goToMainTabBar", sender: nil)
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let vc = segue.destination as? TabBarViewController {
            UIApplication.shared.keyWindow?.rootViewController = vc
        }
    }
    

The app going to crash with:

Application tried to present modal view controller on itself. Presenting controller is TabBarViewController
  1. Next problem is if we set a root in TabBarViewController viewDidLoaded.

    UIApplication.shared.keyWindow?.rootViewController = self

Tab bar items embaded in UINavigationController doesnt have Navigation controller in it selfs, so the nav vc is not instantiated ? Becouse wheenver I will enter into item vc child -> I can't back any more. If i won;t change a root vc there everything is fine.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
yerpy
  • 1,366
  • 3
  • 17
  • 44
  • possible duplicate: https://stackoverflow.com/questions/22653993/programmatically-change-rootviewcontroller-of-storyboard – RLoniello Jan 01 '18 at 22:18
  • @Ercell0 I don't think so, did u read my 2 problems ? – yerpy Jan 01 '18 at 22:20
  • yes i did, perhaps you should continue reading on the issue, you need to embed your VC in a UINavigationController then add that as the root VC: `.rootViewController = UINavigationController(rootViewController: tabVC)` – RLoniello Jan 01 '18 at 22:26

1 Answers1

5

For 1) you can't present a view controller using a segue and then use it to replace the root view controller in the prepare. You will need to instantiate the tab view controller from the storyboard and then replace the root view controller.

Something like this:

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "TabController")
UIApplication.shared.keyWindow?.rootViewController = vc

(assuming the storyboard is called 'Main' and you give the tab controller the storyboard ID of 'TabController'.

I'm not quite clear on what the issue is for 2.

However as a general note I would approach this differently and instead of having the login controller as your initial view controller have the tab bar as the initial controller and then just present the login controller the first time the app starts. That way you avoid replacing the root controller at all and it's all more controlled.

Upholder Of Truth
  • 4,643
  • 2
  • 13
  • 23