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

当前回答

用Swift 3…

另一个可能的原因,发生在我身上,是从一个tableViewCell segue到Storyboard上的另一个ViewController。当单元格被单击时,我还使用override func prepare(for segue: UIStoryboardSegue, sender: Any?){}。

我通过创建一个从ViewController到ViewController的segue来解决这个问题。

其他回答

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

另一个潜在原因:

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

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

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

你从哪里调用这个方法?我有一个问题,我试图在viewDidLoad方法中呈现一个模态视图控制器。我的解决方案是将这个调用移动到viewDidAppear:方法。

我的假设是,视图控制器的视图在它被加载时(当viewDidLoad消息被发送时)不在窗口的视图层次结构中,但在它被呈现后(当viewDidAppear:消息被发送时)它在窗口层次结构中。


谨慎

如果你确实调用了viewDidAppear:中的presentViewController:animated:completion:,你可能会遇到这样一个问题,即每当视图控制器的视图出现时,模态视图控制器总是被呈现(这是有意义的!),因此模态视图控制器被呈现永远不会消失……

也许这不是呈现模态视图控制器的最佳位置,或者可能需要保留一些额外的状态让呈现的视图控制器决定是否应该立即呈现模态视图控制器。

Swift 5 -后台线程

如果一个警报控制器在后台线程上执行,那么“Attempt to present…”“其视图不在窗口层次结构中”的错误可能会发生。

所以这个:

present(alert, animated: true, completion: nil)
    

是这样固定的:

DispatchQueue.main.async { [weak self] in
    self?.present(alert, animated: true, completion: nil)
}