presentViewController 警告视图不在窗口层次结构中

Posted

技术标签:

【中文标题】presentViewController 警告视图不在窗口层次结构中【英文标题】:presentViewController Warning view is not in the window hierarchy 【发布时间】:2015-03-20 18:57:10 【问题描述】:

我在 AppDelegate 的 application:didFinishLaunching 方法中加载 LaunchViewController 作为根视图控制器:

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"LaunchViewController" bundle:nil];
    LaunchViewController *launchViewController = [storyboard instantiateInitialViewController];
    launchViewController.managedObjectContext = [CurrentSession mainQueueContext];
    self.window.rootViewController = launchViewController;
    [self.window makeKeyAndVisible];

LaunchViewController 与 Web 服务器通信以获取一些数据。我正在使用 AFNetworking 库与 Web 服务器进行异步通信。在获取数据后的成功回调中,我展示了 LoginViewController。我的理解是 AFNetworking 的回调是在主线程上执行的。尽管如此,我还是使用performSelectionOnMainThread 来看看这是否能解决问题:

内部回调:

 [self performSelectorOnMainThread:@selector(presentLoginView) withObject:nil waitUntilDone:NO];

presentLoginView方法:

- (void)presentLoginView 
    LoginViewController *loginViewController = [[LoginViewController alloc] initWithNibName:@"LoginViewController" bundle:nil];
    loginViewController.managedObjectContext = self.managedObjectContext;
    [self presentViewController:loginViewController animated:YES completion:nil];

登录视图未显示,在控制台中我看到以下消息:

Warning: Attempt to present <LoginViewController: 0x78e47c30> on <LaunchViewController: 0x78eb4a60> whose view is not in the window hierarchy!

:-(

更新 我在 LoginViewController 的 viewDidLoad、viewDidUnload、viewWillAppear 和 viewDidAppear 方法中设置了断点。 viewDidLoad 被击中。其他人则没有。 为什么视图会加载但不显示?

【问题讨论】:

我遇到了同样的问题,但我只是忽略了它,它仍然可以正常工作。 哦。我想知道在我的情况下发生了什么,因为没有显示登录视图。我之前确实重命名了我的 LoginViewController 的 xib 文件。在代码中,我使用了新的 xib 名称,并确保新的 xib 名称处于目标构建阶段。不知道还能做什么。郁闷。 请问您为什么使用 .xibs? 这是一个旧代码库。 哦,好吧,我帮不了你,但我会等到其他人这样做:D 【参考方案1】:

这可能是因为 AFNetworking 非常快地执行回调,例如在加载视图控制器的视图之前,可能是因为您使用本地服务器或 viewDidLoad 中的其他配置很慢。在这种情况下,我建议将代码移动到 viewWillAppear 或 viewDidAppear,因为此时视图将位于层次结构中,因此您可以从那里呈现另一个 ViewController。

【讨论】:

当用户在 LauncViewController 的视图中点击一个按钮时,会触发通过 AFNetworking 加载数据。所以这发生在 LaunchViewController 的视图加载并显示之后。 在这种情况下,可能与您重命名了 xib 文件有关。尝试检查有关如何加载笔尖和所有者角色的其他问题。 ***.com/questions/19001808/… 我恢复了 xib 重命名。确保旧的 xib 具有正确的文件所有者并且处于构建阶段资源。更改代码以使用旧笔尖名称。并获得相同的行为。【参考方案2】:

在我的 AFNetworking 成功回调中,我将从 Web 服务器获取的一些信息设置为 NSUserDefaults。然后我展示了 LoginViewController。

我的 AppDelegate 正在收听NSUserDefaultsDidChangeNotification 通知。此通知的处理程序会将 launchViewController 设置为根视图控制器。

因此,在 AFNetworking 回调中,当我要求 LaunchViewController 呈现 LoginViewController 时,我还发送了 NSUserDefaultsDidChangeNotification,这将导致 AppDelegate 加载 LaunchViewController。

我从来没有见过 LoginViewController 的闪烁。所以,我认为 AppDelegate 处理程序首先被触发,然后 presentLoginViewController 被调用。这不知何故导致视图没有被添加到窗口层次结构消息中。

【讨论】:

以上是关于presentViewController 警告视图不在窗口层次结构中的主要内容,如果未能解决你的问题,请参考以下文章

presentViewController pushViewController和presentModalViewController

presentViewController pushViewController和presentModalViewController

PresentViewController切换界面

找不到 presentViewController

堆叠 presentViewController 后 statusBarFrame = 0

PresentViewController 故障排除