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

当前回答

你可以调用你的segue或present, push代码在这个块中:

override func viewDidLoad() {
    super.viewDidLoad()
    OperationQueue.main.addOperation {
        // push or present the page inside this block
    }
}

其他回答

另一个潜在原因:

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

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

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

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

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

[self presentViewController:]

我得到一个UIViewController

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

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

当从嵌入在容器中的视图控制器执行segue时,你也可以得到这个警告。正确的解决方案是从容器的父容器使用segue,而不是从容器的视图控制器。

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

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

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

viewWillLayoutSubviews和viewDidLayoutSubviews (iOS 5.0+)可以用于此目的。它们在viewDidAppear之前被调用。