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