尝试呈现其视图不在Windows层次结构中的ViewController

我遇到了一个奇怪的问题:我做了2个视图控制器,以至于我可以用代码切换视图:

var currentViewController:UIViewController=UIApplication.shared.keyWindow!.rootViewController! func showController() { let ViewControllernew1 = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "viewController2") currentViewController.present(ViewControllernew1, animated: true, completion: nil) } 

我的应用程序正确地打开到第一个视图控制器,然后,当我点击在一个精灵套件场景上创build的button,我可以切换到我的新视图控制器成功(我成功显示我的第二个场景),但是,然后,我可以此切换后不再更改我的视图控制器。 如果我再次点击button,我得到这个消息:

尝试在Test_Vuforia.GameViewController上呈现:0x12f549610其视图不在窗口层次结构中!

你知道什么是问题吗? 我知道我在根的位置,所以我不能改变我的视图控制器后,已经切换,但如何改变呢?

谢谢 !

编辑:

我的代码在SKScene中使用,而不是从UIVewController中使用,当我使用后缀self时,出现此错误。 :typesView(SKScene)的值没有成员“存在”。

我正在用Vuforia创build增强现实游戏,我需要用SKScene切换AR视图。

问题

当前viewController不是来自UIApplicationrootViewController 。 所以你应该find当前viewController是可见的,然后从那里展示它。

只需在你的UIApplication Stack上findtopViewController,然后从那里出示你的控制器。

 let newViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "viewController2") UIApplication.topViewController()?.present(newViewController, animated: true, completion: nil) 

UIApplication这个扩展在你的情况下派上用场

 extension UIApplication { class func topViewController(base: UIViewController? = UIApplication.sharedApplication().keyWindow?.rootViewController) -> UIViewController? { if let nav = base as? UINavigationController { return topViewController(base: nav.visibleViewController) } if let tab = base as? UITabBarController { if let selected = tab.selectedViewController { return topViewController(base: selected) } } if let presented = base?.presentedViewController { return topViewController(base: presented) } return base } } 

参考文献: Zammbi

使用下面的扩展名来检索堆栈中下一个可用的控制器。

Swift 3

 extension UIResponder { func next<T: UIResponder>(_ type: T.Type) -> T? { return next as? T ?? next?.next(type) } } 

Swift 2.3

 extension UIResponder { func nextResponder<T: UIResponder>(_ type: T.Type) -> T? { return nextResponder() as? T ?? nextResponder()?.nextResponder(type) } } 

在你的SKSceneview?.next(UIViewController.self)为你提供层次结构中下一个可用的UIViewController

将这个扩展添加到您的项目中名为Categories的组中,如果该组不存在,则创build一个名为UIResponder+NextOfType.swift的新文件并粘贴该扩展。

  1. 可能你的rootViewController不是当前的ViewController 。 要么你提出或推动了一个新的UIViewController的顶部。

  2. viewController's视图不在窗口的视图层次结构中,当它被载入的时候(当viewDidLoad消息被发送的时候),但是在它被呈现之后(当viewDidAppear :消息被发送时)它在窗口层次结构中。 如果你从viewDidLoad调用showController方法,只需从viewDidAppear方法调用它

做类似的事情:

  let vc: UIViewController = (self.storyboard?.instantiateViewControllerWithIdentifier("viewController2"))! self.presentViewController(vc, animated: true, completion: nil) 

  // OR self.navigationController?.pushViewController(vc, animated: true) 

像这样使用

 let vc = self.view?.window?.rootViewController func showController() { let ViewControllernew1 = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "viewController2") vc.present(ViewControllernew1, animated: true, completion: nil) } 

也许问题是与currentViewController。

viewDidAppear调用函数在我的情况有帮助。 解决schemeSwift 3

在您的主控制器中:

 override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) showTutorialModally() } func showTutorialModally() { let tutorialViewController = TutorialViewController() tutorialViewController.modalPresentationStyle = .overCurrentContext present(tutorialViewController, animated: true, completion: nil) } 

在你的教程控制器中:

 view.backgroundColor = UIColor.clear view.isOpaque = false