尝试呈现其视图不在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不是来自UIApplication
的rootViewController
。 所以你应该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) } }
在你的SKScene
, view?.next(UIViewController.self)
为你提供层次结构中下一个可用的UIViewController
。
将这个扩展添加到您的项目中名为Categories的组中,如果该组不存在,则创build一个名为UIResponder+NextOfType.swift
的新文件并粘贴该扩展。
-
可能你的
rootViewController
不是当前的ViewController
。 要么你提出或推动了一个新的UIViewController的顶部。 -
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