ios 警告:尝试在视图不在窗口层次结构中的 * 上显示 * - swift
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26022756/
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
Warning: Attempt to present * on * whose view is not in the window hierarchy - swift
提问by Nils Wasell
I'm trying to present a ViewController
ifthere is any saved data in the data model. But I get the following error:
我正在尝试展示数据模型中ViewController
是否有任何保存的数据。但我收到以下错误:
Warning: Attempt to present * on *whose view is not in the window hierarchy"
警告:尝试在视图不在窗口层次结构中的 * 上显示 *
Relevant code:
相关代码:
override func viewDidLoad() {
super.viewDidLoad()
loginButton.backgroundColor = UIColor.orangeColor()
var request = NSFetchRequest(entityName: "UserData")
request.returnsObjectsAsFaults = false
var appDel:AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
var context:NSManagedObjectContext = appDel.managedObjectContext!
var results:NSArray = context.executeFetchRequest(request, error: nil)!
if(results.count <= 0){
print("Inga resultat")
} else {
print("SWITCH VIEW PLOX")
let internVC = self.storyboard?.instantiateViewControllerWithIdentifier("internVC") as internViewController
self.presentViewController(internVC, animated: true, completion: nil)
}
}
I've tried different solutions found using Google without success.
我尝试了使用 Google 找到的不同解决方案,但没有成功。
回答by Acey
At this point in your code the view controller's view has only been created but not added to any view hierarchy. If you want to present from that view controller as soon as possible you should do it in viewDidAppear
to be safest.
在您的代码中,此时仅创建了视图控制器的视图,但未将其添加到任何视图层次结构中。如果您想尽快从该视图控制器呈现,您应该这样做以viewDidAppear
确保安全。
回答by akr ios
In objective c: This solved my problem when presenting viewcontroller on top of mpmovieplayer
在目标 c 中:这解决了我在 mpmovieplayer 上呈现视图控制器时的问题
- (UIViewController*) topMostController
{
UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
while (topController.presentedViewController) {
topController = topController.presentedViewController;
}
return topController;
}
回答by Jason
Swift 3
斯威夫特 3
I had this keep coming up as a newbie and found that present loads modal views that can be dismissed but switching to root controller is best if you don't need to show a modal.
作为新手,我不断出现这种情况,并发现当前加载的模式视图可以关闭,但如果您不需要显示模式,最好切换到根控制器。
I was using this
我正在使用这个
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard?.instantiateViewController(withIdentifier: "MainAppStoryboard") as! TabbarController
present(vc, animated: false, completion: nil)
Using this instead with my tabController:
将它与我的 tabController 一起使用:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let view = storyboard.instantiateViewController(withIdentifier: "MainAppStoryboard") as UIViewController
let appDelegate = UIApplication.shared.delegate as! AppDelegate
//show window
appDelegate.window?.rootViewController = view
Just adjust to a view controller if you need to switch between multiple storyboard screens.
如果您需要在多个故事板屏幕之间切换,只需调整到视图控制器。
回答by Jacob F. Davis C-CISO
Swift 3.
斯威夫特 3.
Call this function to get the topmost view controller, then have that view controller present.
调用此函数以获取最顶层的视图控制器,然后显示该视图控制器。
func topMostController() -> UIViewController {
var topController: UIViewController = UIApplication.shared.keyWindow!.rootViewController!
while (topController.presentedViewController != nil) {
topController = topController.presentedViewController!
}
return topController
}
Usage:
用法:
let topVC = topMostController()
let vcToPresent = self.storyboard!.instantiateViewController(withIdentifier: "YourVCStoryboardID") as! YourViewController
topVC.present(vcToPresent, animated: true, completion: nil)
回答by Edward
You just need to perform a selector with a delay - (0 seconds works).
您只需要延迟执行选择器 - (0 秒有效)。
override func viewDidLoad() {
super.viewDidLoad()
perform(#selector(presentExampleController), with: nil, afterDelay: 0)
}
@objc private func presentExampleController() {
let exampleStoryboard = UIStoryboard(named: "example", bundle: nil)
let exampleVC = storyboard.instantiateViewController(withIdentifier: "ExampleVC") as! ExampleVC
present(exampleVC, animated: true)
}
回答by Viennarz Valdevieso Curtiz
for SWIFT
为 SWIFT
func topMostController() -> UIViewController {
var topController: UIViewController = UIApplication.sharedApplication().keyWindow!.rootViewController!
while (topController.presentedViewController != nil) {
topController = topController.presentedViewController!
}
return topController
}
回答by Allen Wixted
Swift 4
斯威夫特 4
func topMostController() -> UIViewController {
var topController: UIViewController = UIApplication.shared.keyWindow!.rootViewController!
while (topController.presentedViewController != nil) {
topController = topController.presentedViewController!
}
return topController
}
回答by Bohdan Savych
I was getting this error while was presenting controller after the user opens the deeplink.
I know this isn't the best solution, but if you are in short time frame here is a quick fix - just wrap your code in asyncAfter
:
用户打开深层链接后,在呈现控制器时出现此错误。我知道这不是最好的解决方案,但如果您的时间很短,这里有一个快速解决方案 - 只需将您的代码包装在asyncAfter
:
DispatchQueue.main.asyncAfter(deadline: .now() + 0.7, execute: { [weak self] in
navigationController.present(signInCoordinator.baseController, animated: animated, completion: completion)
})
It will give time for your presenting controller to call viewDidAppear
.
它将为您的演示控制器留出时间调用viewDidAppear
.
回答by Hiren Panchal
For swift 3.0 and above
对于 swift 3.0 及以上
public static func getTopViewController() -> UIViewController?{
if var topController = UIApplication.shared.keyWindow?.rootViewController
{
while (topController.presentedViewController != nil)
{
topController = topController.presentedViewController!
}
return topController
}
return nil}
回答by Xiaohan Chen
I have tried so many approches! the only useful thing is:
我已经尝试了很多方法!唯一有用的是:
if var topController = UIApplication.shared.keyWindow?.rootViewController
{
while (topController.presentedViewController != nil)
{
topController = topController.presentedViewController!
}
}