刚开始使用Xcode 4.5,我在控制台得到了这个错误:

警告:试图在< ViewController: 0x1ec3e000>上显示< finishViewController: 0x1e56e0a0 >,其视图不在窗口层次结构中!

视图仍在显示,应用程序中的一切都在正常工作。这是iOS 6的新功能吗?

这是我用来在视图之间更改的代码:

UIStoryboard *storyboard = self.storyboard;
finishViewController *finished = 
[storyboard instantiateViewControllerWithIdentifier:@"finishViewController"];

[self presentViewController:finished animated:NO completion:NULL];

当前回答

这发生在我身上,当我试图呈现到我的navigationController时,它的视图还没有呈现到视图层次结构上。我解决这个问题的方法是听NavigationControllerDelegate的didShow方法。一旦didShow方法被调用,我知道我可以呈现到我的navigationController上。

注意:使用dispatchQueueAsync.await(.now()) {//present}确实有效,但如果视图需要很长时间才能显示到视图层次结构上,那么它就很容易出错。

其他回答

要将任何子视图显示到主视图,请使用以下代码

UIViewController *yourCurrentViewController = [UIApplication sharedApplication].keyWindow.rootViewController;

while (yourCurrentViewController.presentedViewController) 
{
   yourCurrentViewController = yourCurrentViewController.presentedViewController;
}

[yourCurrentViewController presentViewController:composeViewController animated:YES completion:nil];

对于从主视图中解散任何子视图,请使用以下代码

UIViewController *yourCurrentViewController = [UIApplication sharedApplication].keyWindow.rootViewController;

while (yourCurrentViewController.presentedViewController) 
{
   yourCurrentViewController = yourCurrentViewController.presentedViewController;
}

[yourCurrentViewController dismissViewControllerAnimated:YES completion:nil];

另一个潜在原因:

当我不小心两次呈现同一个视图控制器时,我就遇到了这个问题。(第一次使用performSegueWithIdentifer:sender:当按钮被按下时调用,第二次使用直接连接到按钮的segue)。

实际上,两个segue同时被触发,我得到了错误:试图在Y上显示X,其视图不在窗口层次结构中!

这发生在我身上,当我试图呈现到我的navigationController时,它的视图还没有呈现到视图层次结构上。我解决这个问题的方法是听NavigationControllerDelegate的didShow方法。一旦didShow方法被调用,我知道我可以呈现到我的navigationController上。

注意:使用dispatchQueueAsync.await(.now()) {//present}确实有效,但如果视图需要很长时间才能显示到视图层次结构上,那么它就很容易出错。

如果其他解决方案因为某些原因看起来不太好,你仍然可以使用这个不错的老方法,用延迟0表示,就像这样:

dispatch_after(0, dispatch_get_main_queue(), ^{
    finishViewController *finished = [self.storyboard instantiateViewControllerWithIdentifier:@"finishViewController"];
    [self presentViewController:finished animated:NO completion:NULL];    
});

虽然我没有看到任何文件保证你的VC会在调度块计划执行的时间上处于视图层次结构上,但我观察到它会工作得很好。

使用延迟,例如0.2秒也是一种选择。最好的事情-这样你就不需要在viewDidAppear中混乱布尔变量:

    let alert = UIAlertController(title: "", message: "YOU SUCCESSFULLY\nCREATED A NEW\nALERT CONTROLLER", preferredStyle: .alert)
    func okAlert(alert: UIAlertAction!)
    {
        
    }
    alert.addAction(UIAlertAction(title: "OK", style: .default, handler: okAlert))
    
    let scenes = UIApplication.shared.connectedScenes
    let windowScene = scenes.first as? UIWindowScene
    let window = windowScene?.windows.first
    var rootVC = window?.rootViewController
    
    if var topController = rootVC
    {
        while let presentedViewController = topController.presentedViewController
        {
            topController = presentedViewController
        }
        rootVC = topController
    }
    rootVC?.present(alert, animated: true, completion: nil)