ios 尝试在视图不在窗口层次结构中的 UIViewController 上显示 UIViewController
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11862883/
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 UIViewController on UIViewController whose view is not in the window hierarchy
提问by Kyle Goslan
Just started using Xcode 4.5 and I got this error in the console:
刚开始使用 Xcode 4.5,我在控制台中收到此错误:
Warning: Attempt to present < finishViewController: 0x1e56e0a0 > on < ViewController: 0x1ec3e000> whose view is not in the window hierarchy!
警告:尝试在视图不在窗口层次结构中的 < ViewController: 0x1ec3e000> 上呈现 < finishViewController: 0x1e56e0a0 > !
The view is still being presented and everything in the app is working fine. Is this something new in iOS 6?
该视图仍在呈现,应用程序中的一切正常。这是 iOS 6 中的新功能吗?
This is the code I'm using to change between views:
这是我用来在视图之间切换的代码:
UIStoryboard *storyboard = self.storyboard;
finishViewController *finished =
[storyboard instantiateViewControllerWithIdentifier:@"finishViewController"];
[self presentViewController:finished animated:NO completion:NULL];
回答by James Bedford
Where are you calling this method from? I had an issue where I was attempting to present a modal view controller within the viewDidLoad
method. The solution for me was to move this call to the viewDidAppear:
method.
你从哪里调用这个方法?我在尝试在方法中呈现模态视图控制器时遇到了问题viewDidLoad
。我的解决方案是将此调用移至该viewDidAppear:
方法。
My presumption is that the view controller's view is notin the window's view hierarchy at the point that it has been loaded (when the viewDidLoad
message is sent), but it isin the window hierarchy after it has been presented (when the viewDidAppear:
message is sent).
我的假设是视图控制器的观点是不是在窗口的视图层次的,它已经加载点(当viewDidLoad
发送邮件),但它是在窗口层次结构已经呈现后(当viewDidAppear:
发送消息) .
Caution
警告
If you do make a call to presentViewController:animated:completion:
in the viewDidAppear:
you may run into an issue whereby the modal view controller is always being presented whenever the view controller's view appears (which makes sense!) and so the modal view controller being presented will never go away...
如果您确实调用presentViewController:animated:completion:
inviewDidAppear:
您可能会遇到一个问题,即每当视图控制器的视图出现时,模态视图控制器总是被呈现(这是有道理的!),因此被呈现的模态视图控制器永远不会消失.. .
Maybe this isn't the best place to present the modal view controller, or perhaps some additional state needs to be kept which allows the presenting view controller to decide whether or not it should present the modal view controller immediately.
也许这不是呈现模态视图控制器的最佳位置,或者可能需要保留一些额外的状态,以允许呈现视图控制器决定是否应该立即呈现模态视图控制器。
回答by Chris Nolet
Another potential cause:
另一个潜在原因:
I had this issue when I was accidentally presenting the same view controller twice. (Once with performSegueWithIdentifer:sender:
which was called when the button was pressed, and a second time with a segue connected directly to the button).
当我不小心两次呈现相同的视图控制器时,我遇到了这个问题。(performSegueWithIdentifer:sender:
当按下按钮时调用一次,第二次使用直接连接到按钮的 segue)。
Effectively, two segues were firing at the same time, and I got the error: Attempt to present X on Y whose view is not in the window hierarchy!
实际上,两个 segue 同时触发,我得到了错误: Attempt to present X on Y whose view is not in the window hierarchy!
回答by Jonny
viewWillLayoutSubviews
and viewDidLayoutSubviews
(iOS 5.0+) can be used for this purpose. They are called earlier than viewDidAppear.
viewWillLayoutSubviews
和viewDidLayoutSubviews
(iOS 5.0+) 可用于此目的。它们在 viewDidAppear 之前被调用。
回答by abdul sathar
For Display any subview to main view,Please use following code
要将任何子视图显示到主视图,请使用以下代码
UIViewController *yourCurrentViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
while (yourCurrentViewController.presentedViewController)
{
yourCurrentViewController = yourCurrentViewController.presentedViewController;
}
[yourCurrentViewController presentViewController:composeViewController animated:YES completion:nil];
For Dismiss any subview from main view,Please use following code
对于从主视图中关闭任何子视图,请使用以下代码
UIViewController *yourCurrentViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
while (yourCurrentViewController.presentedViewController)
{
yourCurrentViewController = yourCurrentViewController.presentedViewController;
}
[yourCurrentViewController dismissViewControllerAnimated:YES completion:nil];
回答by sunkehappy
I also encountered this problem when I tried to present a UIViewController
in viewDidLoad
. James Bedford's answer worked, but my app showed the background first for 1 or 2 seconds.
当我尝试UIViewController
在viewDidLoad
. James Bedford 的回答有效,但我的应用程序首先显示了 1 或 2 秒的背景。
After some research, I've found a way to solve this using the addChildViewController
.
经过一番研究,我找到了一种使用addChildViewController
.
- (void)viewDidLoad
{
...
[self.view addSubview: navigationViewController.view];
[self addChildViewController: navigationViewController];
...
}
回答by Sanbrother
Probably, like me, you have a wrong root viewController
可能和我一样,你有一个错误的根 viewController
I want to display a ViewController
in a non-UIViewController
context,
我想ViewController
在non-UIViewController
上下文中显示一个,
So I can't use such code:
所以我不能使用这样的代码:
[self presentViewController:]
So, I get a UIViewController:
所以,我得到了一个 UIViewController:
[[[[UIApplication sharedApplication] delegate] window] rootViewController]
For some reason (logical bug), the rootViewController
is something other than expected (a normal UIViewController
). Then I correct the bug, replacing rootViewController
with a UINavigationController
, and the problem is gone.
由于某种原因(逻辑错误),这rootViewController
不是预期的(正常的UIViewController
)。然后我更正了错误,替换rootViewController
为UINavigationController
,问题就解决了。
回答by Aggressor
TL;DRYou can only have 1 rootViewController and its the most recently presented one. So don't try having a viewcontroller present another viewcontroller when it's already presented one that hasn't been dismissed.
TL;DR你只能有 1 个 rootViewController 和它最近出现的一个。因此,不要尝试让一个视图控制器呈现另一个视图控制器,因为它已经呈现了一个尚未被解雇的视图控制器。
After doing some of my own testing I've come to a conclusion.
在做了一些自己的测试之后,我得出了一个结论。
If you have a rootViewController that you want to present everything then you can run into this problem.
如果您有一个想要呈现所有内容的 rootViewController,那么您可能会遇到这个问题。
Here is my rootController code (open is my shortcut for presenting a viewcontroller from the root).
这是我的 rootController 代码(open 是我从根目录呈现视图控制器的快捷方式)。
func open(controller:UIViewController)
{
if (Context.ROOTWINDOW.rootViewController == nil)
{
Context.ROOTWINDOW.rootViewController = ROOT_VIEW_CONTROLLER
Context.ROOTWINDOW.makeKeyAndVisible()
}
ROOT_VIEW_CONTROLLER.presentViewController(controller, animated: true, completion: {})
}
If I call open twice in a row (regardless of time elapsed), this will work just fine on the first open, but NOT on the second open. The second open attempt will result in the error above.
如果我连续调用 open 两次(无论经过多少时间),这将在第一次打开时正常工作,但不会在第二次打开时正常工作。第二次打开尝试将导致上述错误。
However if I close the most recently presented view then call open, it works just fine when I call open again (on another viewcontroller).
但是,如果我关闭最近呈现的视图然后调用 open,当我再次调用 open (在另一个视图控制器上)时它工作得很好。
func close(controller:UIViewController)
{
ROOT_VIEW_CONTROLLER.dismissViewControllerAnimated(true, completion: nil)
}
What I have concluded is that the rootViewController of only the MOST-RECENT-CALL is on the view Hierarchy (even if you didn't dismiss it or remove a view). I tried playing with all the loader calls (viewDidLoad, viewDidAppear, and doing delayed dispatch calls) and I have found that the only way I could get it to work is ONLY calling present from the top most view controller.
我得出的结论是,只有 MOST-RECENT-CALL 的 rootViewController 位于视图层次结构中(即使您没有关闭它或删除视图)。我尝试使用所有加载器调用(viewDidLoad、viewDidAppear 和延迟调度调用),我发现我可以让它工作的唯一方法是只从最顶层的视图控制器调用 present。
回答by Adam Johns
My issue was I was performing the segue in UIApplicationDelegate
's didFinishLaunchingWithOptions
method before I called makeKeyAndVisible()
on the window.
我的问题是我在调用窗口之前执行了 inUIApplicationDelegate
的didFinishLaunchingWithOptions
方法makeKeyAndVisible()
。
回答by George_E
In my situation, I was not able to put mine in a class override. So, here is what I got:
在我的情况下,我无法将我的置于类覆盖中。所以,这是我得到的:
let viewController = self // I had viewController passed in as a function,
// but otherwise you can do this
// Present the view controller
let currentViewController = UIApplication.shared.keyWindow?.rootViewController
currentViewController?.dismiss(animated: true, completion: nil)
if viewController.presentedViewController == nil {
currentViewController?.present(alert, animated: true, completion: nil)
} else {
viewController.present(alert, animated: true, completion: nil)
}
回答by saltwat5r
This kind of warning can mean that You're trying to present new View Controller
through Navigation Controller
while this Navigation Controller
is currently presenting another View Controller
. To fix it You have to dismiss currently presented View Controller
at first and on completion present the new one.
Another cause of the warning can be trying to present View Controller
on thread another than main
.
这种警告可能意味着你正在尝试提出新的View Controller
通过Navigation Controller
,而这Navigation Controller
是目前呈现的另一个View Controller
。修复它你必须首先关闭当前呈现的View Controller
,并在完成时呈现新的。警告的另一个原因可能是尝试View Controller
在main
.