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

Swift无Storyboard环境下如何在userNotificationCenter中pushViewController

实现Firebase推送通知点击跳转至NavigationController的解决方案

嘿,我来帮你搞定这个点击推送跳转导航控制器的问题!你的现有代码已经有了开头,但核心是要正确获取当前应用的导航控制器实例,而不是新建一个——不然会脱离原有的页面栈,导致跳转逻辑混乱。下面是完整的实现方案:

核心逻辑梳理

  1. 先拿到应用的主窗口,确保能访问到根视图控制器
  2. 根据你的根控制器结构(可能是导航控制器或标签栏控制器),找到当前活跃的导航控制器
  3. 实例化目标页面,按需传递推送里的自定义数据
  4. 把目标页面push到已有导航栈中,同时确保窗口处于活跃状态(处理应用从后台唤醒的场景)

完整代码实现

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    // 1. 获取当前应用的主窗口
    guard let window = UIApplication.shared.windows.first(where: { $0.isKeyWindow }) else {
        completionHandler()
        return
    }
    
    // 2. 找到当前活跃的UINavigationController
    var targetNavController: UINavigationController?
    // 情况1:根控制器直接是导航控制器
    if let rootNav = window.rootViewController as? UINavigationController {
        targetNavController = rootNav
    }
    // 情况2:根控制器是标签栏控制器,取当前选中项的导航控制器
    else if let tabBarVC = window.rootViewController as? UITabBarController {
        targetNavController = tabBarVC.selectedViewController as? UINavigationController
    }
    
    // 如果没找到可用的导航控制器,直接结束流程
    guard let navVC = targetNavController else {
        completionHandler()
        return
    }
    
    // 3. 实例化你要跳转的目标页面(替换成你的实际控制器类)
    let destinationVC = YourTargetViewController()
    
    // 4. 从推送的userInfo里提取自定义数据,传递给目标页面
    let userInfo = response.notification.request.content.userInfo
    // 示例:假设推送里有个"page_id"的自定义字段
    if let pageId = userInfo["page_id"] as? String {
        destinationVC.pageId = pageId
    }
    
    // 5. 执行跳转操作
    navVC.pushViewController(destinationVC, animated: true)
    
    // 6. 确保窗口处于活跃状态(处理应用从后台唤醒的情况)
    window.makeKeyAndVisible()
    
    // 一定要调用completionHandler,通知系统处理完成
    completionHandler()
}

关键注意事项

  • 不要新建导航控制器:你代码里的SomeNavigationController()是个误区,应该复用应用已有的导航栈,否则会导致页面栈混乱,用户返回时找不到之前的页面
  • 适配不同根控制器结构:如果你的根控制器是其他类型(比如自定义容器控制器),需要调整获取导航控制器的逻辑,确保能拿到当前活跃的导航实例
  • 代理设置:确保在AppDelegate或SceneDelegate里设置UNUserNotificationCenter.current().delegate = self,并且你的类遵循UNUserNotificationCenterDelegate协议
  • 处理后台唤醒:加上window.makeKeyAndVisible()可以确保应用从后台唤醒时,窗口能正常显示跳转后的页面

内容的提问来源于stack exchange,提问作者UK4

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:23:24