change root view controller with Side menu

I'm trying to change RootViewController with another ViewController. But I can't figure it out. I'm facing some problems that are

After changed rootViewController by above code then new viewController is disappear. In console log : Presenting view controllers on detached view controllers is discouraged . Please help me!

My code is :

func changeRootView(){
guard let delegate = UIApplication.shared.delegate else {
    return
}
guard let window = (delegate as! AppDelegate).window else {
    return
}
UIView.transition(with: window, duration: 0.3, options: .transitionCrossDissolve, animations: {
    let lgv = DriverMainViewController()
    window.rootViewController = UINavigationViewController(rootViewController: lgv)
}, completion: { completed in
    SideMenuManager.menuLeftNavigationController!.dismiss(animated: true, completion: nil)
    print ("changed")
})

}

Picture before change RootviewController When I clicked that gray button then changeRootView function will run.

Then changeRootView function changed App keyWindow's rootViewController

But this blue backgrounded viewController is disappeared in 1 second. This screen shot is after disappeared new root view controller.

Upvotes: 0

Views: 1406

Answers (1)

Scott Thompson
Scott Thompson

Reputation: 23701

I think what is happening here is that when you set the rootViewController of the window, the old rootViewController is no longer referenced and it gets deleted by ARC. What you might try is capturing the out-going view controller so that it sticks around for the duration of the animation. Try this:

func changeRootView(){
    guard let delegate = UIApplication.shared.delegate else { return }
    guard let window = (delegate as! AppDelegate).window else { return }

    // capture a reference to the old root controller so it doesn't
    // go away until the animation completes
    let oldRootController = window.rootViewController

    UIView.transition(with: window, 
                  duration: 0.3, 
                   options: .transitionCrossDissolve, 
                animations: {
                    let lgv = DriverMainViewController()
                    window.rootViewController = UINavigationViewController(rootViewController: lgv)
                }, 
                completion: { completed in

                    // OK, we're done with the old root controller now
                    oldRootController = nil

                    SideMenuManager.menuLeftNavigationController!.dismiss(animated: true, completion: nil)
                    print ("changed")
                }
    )
}

What this code is doing is adding a reference to the window's existing root view controller and then capturing it in the completion block to control how long it exists.

Upvotes: 1

Related Questions