Swift ios set a new root view controller

2020-02-08 07:32发布

I wonder if its possible to set a new root VC?

My app gets init with a uinavigation controller that has a table view to be the root VC.

Then from the table view I am running another segue to a login window (present modally) If you then login you end up in the red VC/account page. What I want to do now is to set the red VC to be the new root VC of the app, and remove all underlying VC's. So that I can show a menu button/icon instead of a "Back" button

I have found this but I dont understand how to use it:

let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
        let yourViewController: ViewController = storyboard.instantiateViewControllerWithIdentifier("respectiveIdentifier") as! ViewController

        let navigationController = self.window?.rootViewController as! UINavigationController
        navigationController.setViewControllers([yourViewController], animated: true)

But I cannot get it to work. So is it possible to make the red vc in the picture act as the new root VC.

enter image description here

18条回答
地球回转人心会变
2楼-- · 2020-02-08 08:17

How and from where are you presenting redVC?

You could make it root view controller of your UINavigationController, so you would still have ability to push and pop view controllers.

self.navigationController?.viewControllers = [self];
查看更多
啃猪蹄的小仙女
3楼-- · 2020-02-08 08:20

Link to a related question

This answer applies to usage of an existing ViewController from somewhere in the current stack without instantiating and reconfiguring a new controller.

The documentation says: The root view controller provides the content view of the window. Assigning a view controller to this property (either programmatically or using Interface Builder) installs the view controller’s view as the content view of the window. The new content view is configured to track the window size, changing as the window size changes. If the window has an existing view hierarchy, the old views are removed before the new ones are installed.

Just as the documentation says: It removes all views in the stack if the rootViewController is exchanged. No matter what's with the controller. So remove the ViewController from the stack to assure its view won't be removed.

This resulted in my case in the following solution:

    if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
        guard let pageVC = self.onboardingDelegate as? OnboardingPageViewController else { return } // my current stack is in a pageViewController, it also is my delegate
        let vc = self // holding myself
        pageVC.subViewControllers.removeLast() // removing myself from the list
        pageVC.setViewControllers([pageVC.subViewControllers[0]], direction: .forward, animated: false, completion: nil) // remove the current presented VC
        appDelegate.window?.rootViewController = vc
        vc.onboardingDelegate = nil
        appDelegate.window?.makeKeyAndVisible()
    }
查看更多
再贱就再见
4楼-- · 2020-02-08 08:20

Any view controller you want to set root just call the below function like

  UIApplication.shared.setRootVC(vc)

  extension UIApplication {

    func setRootVC(_ vc : UIViewController){

        self.windows.first?.rootViewController = vc
        self.windows.first?.makeKeyAndVisible()

      }
  }
查看更多
Root(大扎)
5楼-- · 2020-02-08 08:21

If you need to set rootViewController with some animations, here is the code:

guard let window = UIApplication.shared.keyWindow else {
    return
}

guard let rootViewController = window.rootViewController else {
    return
}

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "MainTabbar")
vc.view.frame = rootViewController.view.frame
vc.view.layoutIfNeeded()

UIView.transition(with: window, duration: 0.3, options: .transitionCrossDissolve, animations: {
    window.rootViewController = vc
}, completion: { completed in
    // maybe do something here
})
查看更多
【Aperson】
6楼-- · 2020-02-08 08:22

Swift 4 Answer

let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewController(withIdentifier: "YourViewController") as! YourViewController
let navigationController = UINavigationController(rootViewController: nextViewController)            
let appdelegate = UIApplication.shared.delegate as! AppDelegate
appdelegate.window!.rootViewController = navigationController
查看更多
叼着烟拽天下
7楼-- · 2020-02-08 08:22

You can use this code when you click the login button :-

let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
var vc = mainStoryboard.instantiateViewControllerWithIdentifier("respectiveIdentifier") as ViewController  
UIApplication.sharedApplication().keyWindow.rootViewController = vc
查看更多
登录 后发表回答