刚开始使用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];

当前回答

我通过将start()函数移动到解散完成块内部来修复它:

self.tabBarController.dismiss(animated: false) {
  self.start()
}

Start包含对self.present()的两个调用,一个用于UINavigationController,另一个用于UIImagePickerController。

这为我解决了问题。

其他回答

我修复了这个错误,将最顶部的视图控制器存储为常量,这是在rootViewController的while循环中发现的:

if var topController = UIApplication.shared.keyWindow?.rootViewController {
    while let presentedViewController = topController.presentedViewController {
        topController = presentedViewController
    }
    topController.present(controller, animated: false, completion: nil)
    // topController should now be your topmost view controller
}

可能和我一样,你有一个错误的根viewController

我想在非uiviewcontroller上下文中显示一个ViewController,

所以我不能使用这样的代码:

[self presentViewController:]

我得到一个UIViewController

[[[[UIApplication sharedApplication] delegate] window] rootViewController]

由于某种原因(逻辑错误),rootViewController是其他的东西比预期的(一个正常的UIViewController)。然后我纠正了这个错误,用UINavigationController替换了rootViewController,问题就解决了。

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

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

当我试图在viewDidLoad中呈现一个UIViewController时,我也遇到了这个问题。James Bedford的答案是可行的,但我的应用程序先显示了1到2秒的背景。

经过一些研究,我找到了一种方法来解决这个使用addChildViewController。

- (void)viewDidLoad
{
    ...
    [self.view addSubview: navigationViewController.view];
    [self addChildViewController: navigationViewController];
    ...
}

使用故事板,我注意到我有一个按钮连接到两个@IBActions,这两个@IBActions函数分别呈现一个ViewController。在我移除一个连接后,问题就解决了。