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

当前回答

如果你有播放视频的AVPlayer对象,你必须先暂停视频。

其他回答

我已经结束了这样一个代码,最终工作给我(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
        })
    }
}

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

我也有这个问题,但这和时间无关。我使用一个单例来处理场景,并将其设置为presenter。换句话说,“自我”没有连接到任何东西。我只是把它的内部“场景”变成了新的主持人,瞧,它成功了。(瞧,当你知道它的意思后,它就失去了它的触感,嘿)。

所以,这不是关于“神奇地找到正确的方法”,而是关于理解你的代码所处的位置以及它在做什么。我很高兴苹果给出了如此直白的警告信息,甚至还带有感情色彩。向苹果开发者致敬!!

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

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

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

遗憾的是,这个公认的解决方案并不适用于我的案例。我试图在从另一个视图控制器unwind后导航到一个新的视图控制器。

我找到了一个解决方案,使用一个标志来指示哪个unwind segue被调用。

@IBAction func unwindFromAuthenticationWithSegue(segue: UIStoryboardSegue) {
    self.shouldSegueToMainTabBar = true
}

@IBAction func unwindFromForgetPasswordWithSegue(segue: UIStoryboardSegue) {
    self.shouldSegueToLogin = true
}

然后用present(_ viewcontrollertoppresent: UIViewController)来呈现想要的VC

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    if self.shouldSegueToMainTabBar {
        let mainTabBarController = storyboard.instantiateViewController(withIdentifier: "mainTabBarVC") as! MainTabBarController
        self.present(mainTabBarController, animated: true)
        self.shouldSegueToMainTabBar = false
    }
    if self.shouldSegueToLogin {
        let loginController = storyboard.instantiateViewController(withIdentifier: "loginVC") as! LogInViewController
        self.present(loginController, animated: true)
        self.shouldSegueToLogin = false
    }
}

基本上,上面的代码将让我从login/SignUp VC捕获unwind并导航到仪表板,或者从forget password VC捕获unwind操作并导航到登录页面。