You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 08:06:04