刚开始使用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];
可能和我一样,你有一个错误的根viewController
我想在非uiviewcontroller上下文中显示一个ViewController,
所以我不能使用这样的代码:
[self presentViewController:]
我得到一个UIViewController
[[[[UIApplication sharedApplication] delegate] window] rootViewController]
由于某种原因(逻辑错误),rootViewController是其他的东西比预期的(一个正常的UIViewController)。然后我纠正了这个错误,用UINavigationController替换了rootViewController,问题就解决了。
如果其他解决方案因为某些原因看起来不太好,你仍然可以使用这个不错的老方法,用延迟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中混乱布尔变量:
该消息显示为警告,有时代码拒绝工作。(!引文:更新的SDK可能有严格的规则)。
我遇到这种情况的原因不止一个,主要是复杂的视图控制器场景。举个例子。
Scenario: MainViewController (responsible to load: ViewControllerA & ViewControllerB)
从MainViewController中呈现ViewControllerA,并且在不解散ViewControllerA的情况下,尝试从MainViewController中呈现viewControllerB(使用委托方法)。
在这个场景中,你必须确保你的viewcontrollerera被解散,然后ViewControllerB被调用。
因为在呈现ViewControllerA之后(ViewControllerA开始负责显示视图和视图控制器,当MainViewController尝试加载另一个视图控制器时,它拒绝抛出警告)。
你从哪里调用这个方法?我有一个问题,我试图在viewDidLoad方法中呈现一个模态视图控制器。我的解决方案是将这个调用移动到viewDidAppear:方法。
我的假设是,视图控制器的视图在它被加载时(当viewDidLoad消息被发送时)不在窗口的视图层次结构中,但在它被呈现后(当viewDidAppear:消息被发送时)它在窗口层次结构中。
谨慎
如果你确实调用了viewDidAppear:中的presentViewController:animated:completion:,你可能会遇到这样一个问题,即每当视图控制器的视图出现时,模态视图控制器总是被呈现(这是有意义的!),因此模态视图控制器被呈现永远不会消失……
也许这不是呈现模态视图控制器的最佳位置,或者可能需要保留一些额外的状态让呈现的视图控制器决定是否应该立即呈现模态视图控制器。