警告:尝试呈现其视图不在窗口层次结构中的ViewController

在我的一个应用程序中,我从application didReceiveLocalNotification didReceiveLocalNotification方法中调用了一个viewController。 页面加载成功,但显示警告:

  Warning: Attempt to present <blankPageViewController: 0x1fda5190> on <ViewController: 0x1fd85330> whose view is not in the window hierarchy! 

我的代码如下:

  -(void) application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { blankPageViewController *myView = [[blankPageViewController alloc] initWithNibName:@"blankPageViewController" bundle: nil]; myView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal; [self.viewController presentViewController:myView animated:NO completion:nil]; } 

最后我用下面的代码解决了这个问题。

 -(void) application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; self.blankviewController = [[blankPageViewController alloc] initWithNibName:@"blankPageViewController" bundle:nil]; self.window.rootViewController = self.blankviewController; [self.window makeKeyAndVisible]; } 

 [self.viewController presentViewController:myView animated:NO completion:nil]; 

变成一个function,例如

 - (void)yourNewFunction { [self.viewController presentViewController:myView animated:NO completion:nil]; } 

然后像这样调用它:

 [self performSelector:@selector(yourNewFunction) withObject:nil afterDelay:0.0]; 

在这里描述的问题,为什么这个performSelector:withObject:afterDelay修复这个问题? 因为select器只有在运行循环的下一次运行之前才会被调用。 所以事情有时间安顿下来,你会跳过一个运行循环。

根据我的假设,我感觉就像在myView附加或放置在窗口层次结构中之前,试图从myView呈现myView 。 所以只要确保myView得到出现/附加到窗口后呈现myView

为什么不能在viewDidLoad中显示另一个模式视图控制器?

这可能是因为视图控制器的视图当前没有加载窗口层次结构中,当VC呈现…

 -(void) application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { UINavigationController *navigationController = (UINavigationController*) self.window.rootViewController; rootViewController = [[navigationController viewControllers] objectAtIndex:0]; blankPageViewController *myView = [[blankPageViewController alloc] initWithNibName:@"blankPageViewController" bundle: nil]; [rootViewController presentModalViewController:myView animated:YES]; } 

我遇到了类似的问题,当应用程序进入前台时,我正在从AppDelegate.m中调用presentViewController:

 - (void)applicationWillEnterForeground:(UIApplication *)application { NSDate * lastActive = [[NSUserDefaults standardUserDefaults] objectForKey:@"lastActive"]; double interval = [[NSDate date] timeIntervalSinceDate:lastActive]; NSLog(@"Time Interval: %f", interval); if (interval > 900) { // interval is in seconds, so 900 seconds = 15 mins Login *pres = [self.window.rootViewController.storyboard instantiateViewControllerWithIdentifier:@"login"]; UINavigationController *navi = ((UINavigationController*)self.window.rootViewController); if (navi.presentedViewController) { [navi dismissViewControllerAnimated:YES completion:^{ [navi presentViewController:pres animated:NO completion:nil]; }]; } else { [navi presentViewController:pres animated:NO completion:nil]; } } } 

如果它在呈现Login视图控制器之前就已经存在了,那么这个工作就没有问题了,因为它首先closures了视图控制器(无论视图是否被压入)。 如果没有,那么我可以直接提交login视图控制器。

边缘案例:

有些人可能会通过Google发现这一点,值得指出的是,如果您将视图加载为根视图控制器,而不是作为Storyboard(和另一个视图)中的初始视图标记,则有时会出现此错误,加载另一个视图顶部。 例如,在“login视图”中,这是从applicationdidfinish...程序委托的applicationdidfinish...方法中以编程方式加载的。 只需更改初始视图(将Storyboard中的箭头拖动到适合您​​的层次结构的适当位置)。 深奥,含糊,但值得指出。

如果你的应用程序types为UINavigationController,那么你可以使用。

 -(void) application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { blankPageViewController *myView = [[blankPageViewController alloc] initWithNibName:@"blankPageViewController" bundle: nil]; myView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal; [self.navigationController presentViewController:myView animated:NO completion:nil]; } 

希望这会帮助你。 祝一切顺利 !!!

对于Swift 2.0我使用了一个覆盖viewDidAppear

让vc = self.storyboard?.instantiateViewControllerWithIdentifier(“Second”)as! SecondViewController

 self.presentViewController(vc, animated: true, completion: nil) 

其中“Second”是身份检查器中SecondViewController的storyboard ID。

 I have used Navigation Controller and on which i have used a ModalViewController to present a Popup(Present over current context). From this Popup i am opening a ViewController Modally which caused the Warning. So to resolve i did below change: [self.presentedViewController performSegueWithIdentifier:@"PresentScreenSegueId" sender:sender];