我遇到一个奇怪的问题:我制作了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)
}
我的应用程序正确打开第一个视图控制器,然后,当我点击精灵工具包场景中创建的按钮时,我可以成功地将视图切换到我的新视图控制器(我成功显示了第二个场景)但是然后,此切换后我无法再更改视图控制器。如果我再次点击按钮,我收到此消息:
尝试在Test_Vuforia.GameViewController上显示:0x12f549610,其视图不在窗口层次结构中!
你知道这是什么问题吗?我知道我处于根本位置,以便在切换之后我不能再改变我的视图控制器,但是如何改变它?
谢谢!
编辑:
我的代码在SKScene中使用,而不是在UIVewController中使用,当我使用后缀self时,我收到此错误。 :View类型的值(SKScene)没有成员'present'。
我正在用Vuforia创建一个增强现实游戏,我需要用SKScene切换AR视图。
答案 0 :(得分:27)
当前的viewController不是来自rootViewController
的{{1}}。所以你应该找到当前可见的viewController然后从那里呈现它。
只需在UIApplication
上找到topViewController,然后从那里找到您的控制器。
UIApplication Stack
此let newViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "viewController2")
UIApplication.topViewController()?.present(newViewController, animated: true, completion: nil)
的扩展名为您的案例派上用场
UIApplication
参考文献:Gist
答案 1 :(得分:3)
在 viewDidAppear 中调用函数有助于我的情况。解决方案 Swift 3 :
在主控制器中:
MFMailComposerViewController
在您的教程控制器中:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
showTutorialModally()
}
func showTutorialModally() {
let tutorialViewController = TutorialViewController()
tutorialViewController.modalPresentationStyle = .overCurrentContext
present(tutorialViewController, animated: true, completion: nil)
}
答案 2 :(得分:2)
使用下面的扩展名检索堆栈中的下一个可用控制器。
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
。
将此扩展名添加到项目中名为“类别”的组中,如果该组尚未创建,则创建一个名为UIResponder+NextOfType.swift
的新文件并粘贴扩展名。
答案 3 :(得分:2)
粗略的Xcode错误重要性:此视图不在视图层次结构的窗口中。
我不会想到上面的回答问题,但也许你可能想知道为什么会这样。
但我发现你是这个问题的原因很可能是在ViewController生命周期中的ViewDidLoading切换视图中执行代码。
原因可能是,当初始化期间ViewController实现allco init时,它将异步执行viewWillLoad - &gt; viewDidLoad ... - - - - &gt; viewDidApper。然后可能在viewDidLoad的代码执行中。 ViewController可能不会为Window分配值。 rootViewController。所以我们直接使用[self presentViewController:]会出现这个错误。
建议您将开关的代码移动到ViewDidApper。
我希望它会对你有所帮助。
答案 4 :(得分:1)
像这样使用
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上。
答案 5 :(得分:1)
您的rootViewController
可能不是当前的ViewController
。您可以在其上面展示或推送一个新的UIViewController。
viewController's
视图不在
窗口的视图层次结构在它已加载的时间点(何时
发送viewDidLoad
消息),但它在窗口中
提交后的层次结构(viewDidAppear
时:
消息被发送)。 如果您从中调用showController
方法
viewDidLoad
只需从viewDidAppear
方法
做类似的事情:
let vc: UIViewController = (self.storyboard?.instantiateViewControllerWithIdentifier("viewController2"))!
self.presentViewController(vc, animated: true, completion: nil)
// OR
self.navigationController?.pushViewController(vc, animated: true)