web-dev-qa-db-ja.com

警告:ビューがウィンドウ階層にないViewControllerを表示しようとしています

私のアプリの1つで、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];  
}
31
Vinoy Alexander

最後に、次のコードでその問題を解決しました。

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

プット

[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この問題を修正しますか?セレクターは、実行ループの次の実行まで呼び出されないためです。したがって、物事は落ち着く時間があり、実行ループを1つスキップするだけです。

15
hashier

私の仮定では、self.viewControllerがウィンドウ階層にアタッチまたは配置される前に、self.viewControllerからmyViewを提示しようとしているように感じます。したがって、self.viewControllerがウィンドウに表示/添付された後にmyViewを表示するようにしてください。

モーダルView ControllerがviewDidLoadに別のモードコントローラを表示できないのはなぜですか?

14
βhargavḯ

私は同様の問題を抱えていました。アプリケーションがフォアグラウンドに入ったときに、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 View Controllerを表示する前にView Controllerが存在する場合、(Viewがプッシュされたビューに関係なく)まずView Controllerを閉じるため、これは問題なく機能しました。そうでない場合は、すぐにLogin View Controllerを提示できます。

2
Rob

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];
}
2
BhushanVU

エッジケース:

Googleでこれを見つける人もいるかもしれませんが、ストーリーボードの初期ビューとしてラベル付けされていないビューをルートビューコントローラーとしてロードしている場合(および別のビューは)上部に別のビューをロードします。たとえば、App Delegateのapplicationdidfinish...メソッド内からプログラムでロードされるログインビューで。初期ビューをストーリーボードの矢印をドラッグして、階層に適したビューに変更するだけです。難解であいまいですが、指摘する価値があります。

1
LpLrich
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];
0
Suraj Mirajkar

アプリケーションのタイプが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]; }

これがお役に立てば幸いです。ではごきげんよう !!!

0
Yashesh

ために - Swift 2.0viewDidAppearのオーバーライドを使用しました:

let vc = self.storyboard?.instantiateViewControllerWithIdentifier( "Second")as! SecondViewController

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

「Second」は、IDインスペクターのSecondViewControllerのストーリーボードIDです。

0
Sarah Prata