Objective-C中点击推送在AppDelegate弹窗后无法正常dismiss问题求助
问题根源
你当前的核心问题是直接将App的根视图控制器替换成了ViewControllerC,此时ViewControllerA、ViewControllerB完全没有被加载到视图层级中,既不存在视图栈的前后关系,你在B、C中设置的delegate也没有被正确赋值,点击关闭按钮的回调自然无法生效,也不存在可以dismiss回退的上级页面。
解决方案
不要随意修改App的根视图控制器,而是在原有根视图结构的基础上,按你需要的层级依次弹出视图,修改代码如下:
第一步:在AppDelegate.m中新增获取当前顶层控制器的工具方法
- (UIViewController *)getTopViewController { UIViewController *topVC = self.window.rootViewController; while (topVC.presentedViewController) { topVC = topVC.presentedViewController; if ([topVC isKindOfClass:[UINavigationController class]]) { topVC = [(UINavigationController *)topVC topViewController]; } } return topVC; }
第二步:修改通知跳转逻辑
替换原来直接修改rootViewController的代码,按A->B->C的层级构建视图栈:
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler { NSDictionary *userInfo = response.notification.request.content.userInfo; if ([(userInfo[kGCMMessageIDKey]) isEqual: @"ViewControllerC"]) { UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil]; // 先构建基础根视图结构:导航控制器包裹ViewControllerA ViewControllerA *vcA = [storyboard instantiateViewControllerWithIdentifier:@"ViewControllerA"]; UINavigationController *navVC = [[UINavigationController alloc] initWithRootViewController:vcA]; navVC.modalPresentationStyle = UIModalPresentationFullScreen; // 初始化ViewControllerB并绑定代理 ViewControllerB *vcB = [storyboard instantiateViewControllerWithIdentifier:@"ViewControllerB"]; vcB.delegate = vcA; // 初始化ViewControllerC并绑定代理 ViewControllerC *vcC = [storyboard instantiateViewControllerWithIdentifier:@"ViewControllerC"]; vcC.delegate = vcB; // 获取当前顶层控制器弹出整套视图 UIViewController *topVC = [self getTopViewController]; [topVC presentViewController:navVC animated:YES completion:^{ // 无动画依次弹出B和C,用户感知直接打开C [vcA presentViewController:vcB animated:NO completion:^{ [vcB presentViewController:vcC animated:NO completion:nil]; }]; }]; } else { //go to another vc } NSLog(@"%@", userInfo); completionHandler(); }
注意事项
- 请确保你的Storyboard中已经给ViewControllerA、ViewControllerB设置了和代码中对应的Storyboard ID
- 请确认ViewControllerB、ViewControllerC的头文件中已经正确声明了对应的delegate属性
- 如果你原有页面跳转是使用导航控制器的push而非present实现,只需要把上述present的代码替换为push方法,dismiss替换为对应的pop方法即可,核心逻辑都是保证A->B->C的层级关系完整
内容的提问来源于stack exchange,提问作者14079_Z
相关产品推荐
相关产品推荐

