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

当前回答

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

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

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

其他回答

我在更新Xcode后发现了这个bug,我相信是Swift 5。当我在展开视图控制器后通过编程方式直接启动segue时,问题就发生了。

解决方案到来的同时修复了一个相关的错误,即用户现在可以通过向下滑动页面来unwind segue。这打破了我程序的逻辑。

通过将所有视图控制器上的演示模式从自动更改为全屏,可以解决这个问题。

你可以在界面构建器的属性面板中完成。或者查看这个答案,了解如何以编程方式完成。

如果其他解决方案因为某些原因看起来不太好,你仍然可以使用这个不错的老方法,用延迟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中混乱布尔变量:

这种警告可能意味着你正试图通过导航控制器呈现新的视图控制器,而这个导航控制器目前正在呈现另一个视图控制器。要修复它,你必须首先解散当前呈现的视图控制器,并在完成时呈现新的视图控制器。 警告的另一个原因可能是试图在主线程以外的线程上呈现视图控制器。

它主要发生在你在一些后台工作后,如Api命中或特别核心数据服务调用警报。 在应用程序主线程中调用警报。

DispatchQueue.main.async {
   // call your alert in this main thread.
   Constants.alert(title: "Network Error!", message: "Please connect to internet and try again.", controller: self)
}

我已经结束了这样一个代码,最终工作给我(Swift),考虑到你想要显示一些viewController从几乎任何地方。当没有可用的rootViewController时,这段代码显然会崩溃,这是开放式结局。它也不包括通常需要切换到UI线程使用

dispatch_sync(dispatch_get_main_queue(), {
    guard !NSBundle.mainBundle().bundlePath.hasSuffix(".appex") else {
       return; // skip operation when embedded to App Extension
    }

    if let delegate = UIApplication.sharedApplication().delegate {
        delegate.window!!.rootViewController?.presentViewController(viewController, animated: true, completion: { () -> Void in
            // optional completion code
        })
    }
}