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

当前回答

该消息显示为警告,有时代码拒绝工作。(!引文:更新的SDK可能有严格的规则)。

我遇到这种情况的原因不止一个,主要是复杂的视图控制器场景。举个例子。

Scenario: MainViewController (responsible to load: ViewControllerA & ViewControllerB)

从MainViewController中呈现ViewControllerA,并且在不解散ViewControllerA的情况下,尝试从MainViewController中呈现viewControllerB(使用委托方法)。

在这个场景中,你必须确保你的viewcontrollerera被解散,然后ViewControllerB被调用。

因为在呈现ViewControllerA之后(ViewControllerA开始负责显示视图和视图控制器,当MainViewController尝试加载另一个视图控制器时,它拒绝抛出警告)。

其他回答

遗憾的是,这个公认的解决方案并不适用于我的案例。我试图在从另一个视图控制器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操作并导航到登录页面。

必须写在线下。

self.searchController.definesPresentationContext = true

而不是

self.definesPresentationContext = true

在ui

我有这个问题,根本原因是多次订阅按钮单击处理程序(TouchUpInside)。

它在ViewWillAppear中订阅,它被多次调用因为我们添加了导航去到另一个控制器,然后unwind回它。

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

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

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

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