ios 尝试呈现其视图不在 Windows 层次结构中的 ViewController
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40304405/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Attempt to present ViewController whose view is not in the windows hierarchy
提问by PGibouin
I meet a strange problem: I made 2 view controllers for wich I can switch the view with code:
我遇到了一个奇怪的问题:我制作了 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)
}
My app open correctly to the first view controller, then, when I click on the button created on a sprite kit scene, I can switch the view to my new view controller successfully (I get my second scene successfully showed) but then, I can not change anymore my view controller after this switch. If I click again on the button, I get this message:
我的应用程序正确打开到第一个视图控制器,然后,当我单击在精灵套件场景上创建的按钮时,我可以成功地将视图切换到我的新视图控制器(我成功显示了我的第二个场景)但是,我可以在此切换后不再更改我的视图控制器。如果我再次单击该按钮,则会收到以下消息:
Attempt to present on Test_Vuforia.GameViewController: 0x12f549610 whose view is not in the window hierarchy!
尝试在 Test_Vuforia.GameViewController: 0x12f549610 上显示其视图不在窗口层次结构中!
Do you know what is the problem ? I understand I'm in the root position so that I can not change anymore my view controller after having switched it, but how to change that ?
你知道是什么问题吗?我知道我处于根位置,因此在切换视图控制器后我无法再更改它,但是如何更改它?
Thanks !
谢谢 !
Edit:
编辑:
My code is used inside a SKScene and not from a UIVewController and I get this error when I use the suffix self. : Value of type View (SKScene) has no member 'present'.
我的代码在 SKScene 中使用,而不是来自 UIVewController,当我使用后缀 self. : View (SKScene) 类型的值没有成员“present”。
I'm creating an augmented reality game with Vuforia and I need to switch AR view with SKScene.
我正在使用 Vuforia 创建增强现实游戏,我需要使用 SKScene 切换 AR 视图。
回答by E-Riddie
Issue
问题
Current viewController is not the rootViewController
from UIApplication
. So you should find the current viewController which is visible and then present it from there.
当前 viewController 不是rootViewController
from UIApplication
。所以你应该找到当前可见的 viewController,然后从那里呈现它。
Solution
解决方案
Simply find the topViewController on your UIApplication Stack
, and from there present your controller.
只需在您的 上找到 topViewController UIApplication Stack
,然后从那里展示您的控制器。
let newViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "viewController2")
UIApplication.topViewController()?.present(newViewController, animated: true, completion: nil)
This extension of UIApplication
comes in handy for your case
这个扩展UIApplication
对你的情况很有用
extension UIApplication {
class func topViewController(base: UIViewController? = UIApplication.shared.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
}
}
References: Gist
参考资料:要点
回答by janaz
Calling function in viewDidAppearhelps in my case. Solution for Swift 3:
在viewDidAppear 中调用函数对我有帮助。Swift 3 的解决方案:
In your Main Controller:
在您的主控制器中:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
showTutorialModally()
}
func showTutorialModally() {
let tutorialViewController = TutorialViewController()
tutorialViewController.modalPresentationStyle = .overCurrentContext
present(tutorialViewController, animated: true, completion: nil)
}
In your Tutorial Controller:
在您的教程控制器中:
view.backgroundColor = UIColor.clear
view.isOpaque = false
回答by Jersey
Xcode error significance for roughly: this view is not in the Window of the view hierarchy.
Xcode 的错误含义大致为:这个视图不在视图层次结构的 Window 中。
What I don't think the above answer questions, but maybe you might have wondered why this would happen.
我不认为上面的问题回答了什么,但也许你可能想知道为什么会发生这种情况。
But I find that you are the reasons for this problem is likely to be in the ViewController life cycle at ViewDidLoading switch view Code execution inside.
但是我发现你这个问题的原因很可能是在ViewController生命周期中的ViewDidLoading切换视图代码里面执行的。
Reason is probably that, when the ViewController implementation allco init during initialization, it will be executed asynchronously viewWillLoad - > viewDidLoad... -- -- -- -- > viewDidApper. Then may be in code execution to the viewDidLoad. The ViewController may not assign values to the Window. The rootViewController. So we directly use [self presentViewController:] will appear this error.
原因大概是,ViewController在初始化时执行allco init时,会异步执行viewWillLoad -> viewDidLoad... -- -- -- --> viewDidApper。然后可能会在代码中执行到viewDidLoad。ViewController 可能不会为 Window 分配值。根视图控制器。所以我们直接使用[self presentViewController:]会出现这个错误。
It is recommended that you move the code of the switch to ViewDidApper.
建议将开关的代码移到ViewDidApper。
I hope it will help you.
我希望它会帮助你。
回答by Callam
Use the extension below to retrieve the next available controller in the stack.
使用下面的扩展来检索堆栈中的下一个可用控制器。
Swift 3
斯威夫特 3
extension UIResponder {
func next<T: UIResponder>(_ type: T.Type) -> T? {
return next as? T ?? next?.next(type)
}
}
Swift 2.3
斯威夫特 2.3
extension UIResponder {
func nextResponder<T: UIResponder>(_ type: T.Type) -> T? {
return nextResponder() as? T ?? nextResponder()?.nextResponder(type)
}
}
Inside your SKScene
, view?.next(UIViewController.self)
gives you the next available UIViewController
in the hierarchy.
在 your 中SKScene
,view?.next(UIViewController.self)
为您提供UIViewController
层次结构中的下一个可用。
Add this extension to a group in your project called Categories, if this group does not exist already create it, then create a new file called UIResponder+NextOfType.swift
and paste the extension.
将此扩展名添加到项目中名为 Categories 的组中,如果该组不存在,则创建它,然后创建一个名为的新文件UIResponder+NextOfType.swift
并粘贴该扩展名。
回答by vaibhav
Probably your
rootViewController
is not the currentViewController
. Either you presented or pushed a new UIViewController on top of it.The
viewController's
view is not in the window's view hierarchy at the point that it has been loaded (when theviewDidLoad
message is sent), but it is in the window hierarchy after it has been presented (when theviewDidAppear
: message is sent). if you callingshowController
method fromviewDidLoad
just call it fromviewDidAppear
method
可能你
rootViewController
的不是当前的ViewController
. 你在它上面展示或推送了一个新的 UIViewController 。该
viewController's
视图不是在点窗口的视图层次,它已经被加载(在当viewDidLoad
发送消息),但它是在窗口层次结构已经呈现后(时viewDidAppear
:发送消息)。如果您从方法中调用showController
方法viewDidLoad
只是从viewDidAppear
方法中调用它
Do something like:
做类似的事情:
let vc: UIViewController = (self.storyboard?.instantiateViewControllerWithIdentifier("viewController2"))!
self.presentViewController(vc, animated: true, completion: nil)
// OR
self.navigationController?.pushViewController(vc, animated: true)
回答by Parth Adroja
Use like this
像这样使用
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)
}
Maybe the issue is with the currentViewController.
也许问题出在 currentViewController 上。