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

时间:2013-03-08 05:59:34

标签: ios objective-c xcode uiviewcontroller

在我的一个应用中,我正在使用application 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];  
}

9 个答案:

答案 0 :(得分:21)

最后,我用以下代码解决了这个问题。

-(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];
}

答案 1 :(得分:15)

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

进入一个函数,例如

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

然后像这样调用它:

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

问题被描述为here,为什么performSelector:withObject:afterDelay解决了这个问题?因为在下一次运行循环运行之前不会调用选择器。所以事情有时间安定下来,你将跳过一个运行循环。

答案 2 :(得分:14)

根据我的假设,我觉得您试图在myView附加self.viewController之前尝试展示self.viewController或放置在窗口层次结构中。因此,请确保在myView出现/附加到窗口后显示self.viewController

Why can't a modal view controller present another in viewDidLoad?

答案 3 :(得分:2)

可能是因为当VC出现时,viewcontroller的视图当前没有加载到窗口层次结构中......

-(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];
}

答案 4 :(得分:2)

我遇到了类似的问题,当应用程序进入前台时,我在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视图控制器之前它存在,它首先解除视图控制器(无论哪个视图被推到它上)。如果没有,那么我可以立即呈现Login视图控制器。

答案 5 :(得分:1)

Edge Case:

有些人可能会通过Google找到这一点,并且值得指出的是,如果您将视图加载为根视图控制器(有时未在Storyboard中标记为初始视图),则有时会出现此错误(&amp;另一个视图是)然后你在顶部加载另一个视图。例如,在登录视图中,从App Delegate的applicationdidfinish...方法中以编程方式加载。只需将初始视图(将Storyboard中的箭头拖动)更改为适合您的层次结构的视图。深奥,模糊,但值得指出。

答案 6 :(得分:0)

如果您的应用程序类型为ID 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]; }

希望这会对你有所帮助。 一切顺利!!!

答案 7 :(得分:0)

对于 Swift 2.0 ,我使用了viewDidAppear的覆盖:

让vc = self.storyboard?.instantiateViewControllerWithIdentifier(&#34; Second&#34;)为! SecondViewController

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

Where&#34; Second&#34;是身份检查器中SecondViewController的故事板ID。

答案 8 :(得分:0)

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];