Swift ios设置了一个新的根视图控制器

我想知道它是否有可能设置一个新的根VC?

我的应用程序使用uinavigation控制器获取init,该控制器具有作为根VC的表视图。

然后从表格视图我运行另一个segue到一个登录窗口(以模态呈现)如果你然后登录你最终在红色的 VC /帐户页面。 我现在要做的是将红色VC设置为应用程序的新根VC,并删除所有底层VC。 这样我就可以显示菜单按钮/图标而不是“后退”按钮

我找到了这个,但我不明白如何使用它:

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) 

但我无法让它发挥作用。 因此可以使图中的红色vc充当新的根VC。

在此处输入图像描述

也许你应该试试这个

  let mainStoryBoard = UIStoryboard(name: "Main", bundle: nil) let redViewController = mainStoryBoard.instantiateViewControllerWithIdentifier("respectiveIdentifier") as! ViewController let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate appDelegate.window?.rootViewController = redViewController 

Swift 3更新: –

 let testController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "testController") as! TestController let appDelegate = UIApplication.shared.delegate as! AppDelegate appDelegate.window?.rootViewController = testController 

UINavigationController有一个viewControllers属性,它是一个NSArray,你可以将它替换为你自己的视图控制器的NSArray。

这可以在下面的示例代码中显示。

 let newViewController = self.storyboard?.instantiateViewControllerWithIdentifier("YourViewControllerollerID") as! YourViewController let customViewControllersArray : NSArray = [newViewController] self.navigationController?.viewControllers = customViewControllersArray as! [UIViewController] 

如果你想显示这个新的根视图控制器,你可以调用UINavigationController的popToRootViewController()方法。

 self.navigationController?.popToRootViewControllerAnimated(true) 

为了使原始问题的代码片段起作用,我不得不对第三行进行更改

 let navigationController = self.navigationController! 

我在视图控制器中的@IBAction中使用此代码,该视图控制器位于新的根视图控制器之前。

使用原始代码,我收到一个错误,说我的视图控制器没有名为window成员。 看完文档后 ,我找不到名为window属性。 我想知道上面的原始代码块是否打算在UINavigationController文件中使用。

这是整个块。

 let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle()) let todayViewController: TodaysFrequencyViewController = storyboard.instantiateViewControllerWithIdentifier("todaysFrequency") as! TodaysFrequencyViewController let navigationController = self.navigationController! navigationController.setViewControllers([todayViewControl ler], animated: true) 

Swift 4答案

 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 

我想知道它是否有可能设置一个新的根VC?

是的,这是可能的。 你如何做到这取决于具体情况……

我的应用程序使用uinavigation控制器获取init,该控制器具有作为根VC的表视图。

实际上有两件事通常被称为“根视图控制器”:

  • UIWindow有一个可写的rootViewController属性。

  • UINavigationController没有rootViewController属性,但它有一个名为rootViewController的初始化器-initWithRootViewController: 。 您可以通过设置viewControllers属性来设置导航控制器的“根”视图控制器。

听起来您正在尝试更改窗口的根视图控制器,但您显示的代码只会更改导航控制器的viewControllers属性。 尝试直接设置窗口的rootViewController属性。 但是要明白,如果采用这种方法,那么导航控制器也会消失。 另一方面,如果您想保留导航控制器,请使用当前的方法。

但我无法让它发挥作用。 因此可以使图中的红色vc充当新的根VC。

这里的更多信息会有所帮助。 什么是“无法让它工作”是什么意思? 会发生什么,你期望发生什么?

你可以使用这段代码:

 let newViewController = self.storyboard?.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController let customViewControllersArray : NSArray = [newViewController] self.navigationController?.viewControllers = customViewControllersArray as! [UIViewController] self.navigationController?.pushViewController(newViewController, animated: true) 

单击登录按钮时可以使用此代码: –

 let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil) var vc = mainStoryboard.instantiateViewControllerWithIdentifier("respectiveIdentifier") as ViewController UIApplication.sharedApplication().keyWindow.rootViewController = vc 

您如何以及从何处呈现redVC?

你可以使它成为你的UINavigationController的根视图控制器,所以你仍然可以推送和弹出视图控制器。

 self.navigationController?.viewControllers = [self]; 

一旦你在你想要设置为root的vc中,只需添加你的viewDidLoad

 let appDelegate = UIApplication.shared.delegate as! AppDelegate appDelegate.window?.rootViewController = self 

*根据最佳实践,您应该检查它是否已经是根,如果不执行上面的代码。

Swift 3 AppDelegate文件:::

 @IBAction func btnGoBack(_ sender: UIButton){ self.goToHomeVC() } func goToHomeVC(){ let storyboard = UIStoryboard(name: "Main", bundle: nil) let viewController = storyboard.instantiateViewController(withIdentifier :"HomeVC") as! HomeVC let navController = UINavigationController.init(rootViewController: viewController) if let window = self.appDelegate.window, let rootViewController = window.rootViewController { var currentController = rootViewController while let presentedController = currentController.presentedViewController { currentController = presentedController } currentController.present(navController, animated: true, completion: nil) } } 

斯威夫特4

  let storyBoard = UIStoryboard(name: "Your_Storyboard_Name", bundle:Bundle.main) self.window = UIWindow(frame: UIScreen.main.bounds) let yourVc = storyBoard.instantiateViewController(withIdentifier: "YourIdentifier") as? YourViewController if let window = window { window.rootViewController = yourVc } self.window?.makeKeyAndVisible() 

你可以试试这个代码

 func switchRootViewController(rootViewController: UIViewController, animated: Bool, completion: (() -> Void)?) { guard let window = UIApplication.shared.keyWindow else { return } if animated { UIView.transition(with: window, duration: 0.5, options: .transitionCrossDissolve, animations: { let oldState: Bool = UIView.areAnimationsEnabled UIView.setAnimationsEnabled(false) window.rootViewController = rootViewController UIView.setAnimationsEnabled(oldState) }, completion: { (finished: Bool) -> () in if (completion != nil) { completion!() } }) } else { window.rootViewController = rootViewController } } 

链接到相关问题

此答案适用于从当前堆栈中某处使用现有ViewController,而无需实例化和重新配置新控制器。

文档说:根视图控制器提供窗口的内容视图。 将视图控制器分配给此属性(以编程方式或使用Interface Builder)将视图控制器的视图安装为窗口的内容视图。 新内容视图配置为跟踪窗口大小,随窗口大小的变化而变化。 如果窗口具有现有视图层次结构,则在安装新视图之前将删除旧视图。

正如文档所说: 如果交换了rootViewController,它将删除堆栈中的所有视图。 无论控制器是什么。 因此,从堆栈中删除ViewController以确保其视图不会被删除。

这导致我的案例在以下解决方案中:

  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() }