Warning: Attempt to present xxx on xxx whose view is not in the window hierarchy!

在给KeePassNotes增加手势解锁的过程中,发现切换view时,总是有提示一条warning:

Warning: Attempt to present <UINavigationController: 0x7fbd73461e90> on <UINavigationController: 0x7fbd73556ca0> whose view is not in the window hierarchy!
提示这个warning,原因是因为在当前view尚未绘制完成时,跳转新的view,这样会导致框架不知道当前windows怎样继续绘制,即hierarchy错乱。
presentViewController等执行时间是比较短的,在presentViewController之后的也代码也会继续执行。

故,存在这个问题的可能写法有:
1.在viewDidLoad 弹跳新的YourViewController 时,会出现这个Warning 并且没有任何结果。 
参考: 
http://stackoverflow.com/questions/11862883/whose-view-is-not-in-the-window-hierarchy

http://blog.changyy.org/2014/08/ios-warning-attempt-to-present.html
查询了一下,发现要在viewDidAppear 调用就能避免现象,有人说是在viewDidLoad 时没有Window Hierarchy 资讯。 
摆在viewDidAppear 时,若弹跳的YourViewController 关闭时,切入ViewController 时,
又进入viewDidAppear 又会弹跳YourViewController 出来。 

- (void)viewDidAppear:(BOOL)animated 

[super viewDidAppear:animated]; 
[self presentViewController:[[YourViewController alloc] init] animated:YES completion:NULL]; 
}

或者:
- (void)viewDidLoad 

[super viewDidLoad]; 

dispatch_async(dispatch_get_main_queue(), ^{ 
YourViewController *v = [[YourViewController alloc] init]; 
[self presentViewController:v animated:YES completion:^{}]; 
}); 
}
2。正常跳转时:
///seg
 if ((gesture_unlock_password !=nil)
                    && (gesture_pin!=nil)
                    ) {
                    //gesture unclock
                    NSLog(@"gesture_unlock_password");
                    PFViewController * pfvc = [[PFViewController alloc]init];
                    
                    [pfvc setDBFilename:filename];
                    [self.navigationController presentViewController:pfvc  animated:NO completion:^{
                        NSLog(@"gesture_unlock_password presentViewController finished,openDatabaseDocument:%@",filename);
                    }];
 }
                    NSLog(@"normally openDatabaseDocument filename:%@",filename);
                    // Load the database
                    [[DatabaseManager sharedInstance] openDatabaseDocument:filename animated:YES istouchid:NO];
//seg

==>改动:
在PFViewController内部处理完成后,内部调用一次[[DatabaseManager sharedInstance] openDatabaseDocument:filename animated:YES istouchid:NO];
然后在seg片段,放到else中。
//seg
 if ((gesture_unlock_password !=nil)
                    && (gesture_pin!=nil)
                    ) {
                    //gesture unclock
                    NSLog(@"gesture_unlock_password");
                    PFViewController * pfvc = [[PFViewController alloc]init];
                    
                    [pfvc setDBFilename:filename];
                    [self.navigationController presentViewController:pfvc  animated:NO completion:^{
                        NSLog(@"gesture_unlock_password presentViewController finished,openDatabaseDocument:%@",filename);
                    }];
                }else{
                    NSLog(@"normally openDatabaseDocument filename:%@",filename);
                    // Load the database
                    [[DatabaseManager sharedInstance] openDatabaseDocument:filename animated:YES istouchid:NO];
                }
//seg


| 0个评论