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

技术求助:导航栈中间推入ViewController及App Delegate通知跳转方法

iOS导航跳转常见问题解决方案

嘿,我来帮你搞定这两个iOS开发里的导航问题,都是日常开发中很实用的场景,直接上干货:

1. 在导航控制器的导航栈中间插入任意ViewController

导航控制器的导航栈本质上是一个viewControllers数组,我们可以直接修改这个数组,把新的ViewController插入到任意位置。举个具体的例子:假设当前导航栈是 VC1 -> VC2 -> VC3,我们想在VC2和VC3之间插入一个CustomVC,代码可以这么写:

// 获取当前导航栈的视图控制器数组
guard let navController = self.navigationController else { return }
var currentStack = navController.viewControllers

// 创建要插入的目标ViewController
let customVC = CustomViewController()
// 确定插入位置:比如在索引2的位置(也就是VC3的前面)插入
let insertIndex = 2
currentStack.insert(customVC, at: insertIndex)

// 更新导航栈
navController.viewControllers = currentStack

// 如果插入后想直接跳转到这个新VC,可以加上这句
navController.popToViewController(customVC, animated: true)

这样修改后,导航栈就变成了 VC1 -> VC2 -> CustomVC -> VC3,完全符合“在栈中间推入”的需求。

2. 点击通知时从App Delegate中以普通push方式跳转到任意ViewController

这里要分iOS版本来处理,iOS13之后苹果引入了SceneDelegate,所以我们需要兼容两种情况:

情况1:iOS13之前(仅使用AppDelegate)

在AppDelegate中,我们需要先找到当前活跃的导航控制器,再执行push操作。代码示例如下:

// 处理远程通知的方法
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    handleNotificationJump()
    completionHandler(.newData)
}

// 处理本地通知的方法(如果需要)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    handleNotificationJump()
    completionHandler()
}

// 核心跳转逻辑
private func handleNotificationJump() {
    guard let window = UIApplication.shared.keyWindow else { return }
    var currentNav: UINavigationController?
    
    // 判断根控制器是TabBar还是直接的NavigationController
    if let tabBar = window.rootViewController as? UITabBarController {
        currentNav = tabBar.selectedViewController as? UINavigationController
    } else if let nav = window.rootViewController as? UINavigationController {
        currentNav = nav
    }
    
    // 创建目标ViewController并push
    let targetVC = TargetViewController()
    currentNav?.pushViewController(targetVC, animated: true)
}

情况2:iOS13及以上(兼容SceneDelegate)

iOS13之后,窗口属于具体的Scene,所以我们需要在SceneDelegate中处理跳转:

// SceneDelegate中处理远程通知
func scene(_ scene: UIScene, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
    handleNotificationJump(for: scene)
}

// 核心跳转逻辑
private func handleNotificationJump(for scene: UIScene) {
    guard let windowScene = scene as? UIWindowScene,
          let window = windowScene.windows.first else { return }
    var currentNav: UINavigationController?
    
    if let tabBar = window.rootViewController as? UITabBarController {
        currentNav = tabBar.selectedViewController as? UINavigationController
    } else if let nav = window.rootViewController as? UINavigationController {
        currentNav = nav
    }
    
    let targetVC = TargetViewController()
    currentNav?.pushViewController(targetVC, animated: true)
}

要注意的是,如果你用了UNUserNotificationCenter,记得在AppDelegate或SceneDelegate的初始化方法中设置代理:UNUserNotificationCenter.current().delegate = self。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:26:26