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

iOS15/Xcode13下SwiftUI无Storyboard点击推送通知跳转指定视图如何实现

SwiftUI 无Storyboard项目推送点击跳转到指定视图实现方案

核心思路是通过全局状态驱动界面跳转,替代UIKit时代直接操作视图控制器的逻辑。

步骤1:创建全局路由状态管理类

定义全局可观察的路由对象,统一控制Tab选中状态和页面导航路径:

import SwiftUI

@MainActor
final class AppRoute: ObservableObject {
    // 对应TabView的选中索引,假设消息页是第二个Tab,tag设置为1
    @Published var selectedTab: Int = 0
    // 若需要进入消息页后继续跳转内部子页面,可使用NavigationPath控制
    @Published var messagesNavPath = NavigationPath()
}

步骤2:实现AppDelegate逻辑

在通知点击回调中修改全局路由状态,完成跳转触发:

import UIKit
import UserNotifications

class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDelegate {
    // 持有全局路由对象
    var appRoute: AppRoute?
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        // 设置通知中心代理
        UNUserNotificationCenter.current().delegate = self
        return true
    }
    
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        Task { @MainActor in
            // 切换到消息页对应的Tab
            appRoute?.selectedTab = 1
            // 如果需要跳转到消息页内部的某个子页面,可追加对应路径
            // appRoute?.messagesNavPath.append(你的消息详情数据模型)
        }
        completionHandler()
    }
}

步骤3:App入口注入全局状态

在项目入口处初始化路由对象,同时注入到AppDelegate和视图环境中:

@main
struct MyApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    @StateObject private var appRoute = AppRoute()
    
    init() {
        // 给AppDelegate绑定全局路由对象
        appDelegate.appRoute = appRoute
    }
    
    var body: some Scene {
        WindowGroup {
            MainTabView()
                .environmentObject(appRoute)
        }
    }
}

步骤4:绑定TabView的选中状态

将TabView的选中属性和全局路由状态绑定,保证状态修改可以同步切换Tab:

struct MainTabView: View {
    @EnvironmentObject var appRoute: AppRoute
    
    var body: some View {
        TabView(selection: $appRoute.selectedTab) {
            HomeView()
                .tabItem { Label("首页", systemImage: "house") }
                .tag(0)
            
            MessagesView()
                .tabItem { Label("消息", systemImage: "message") }
                .tag(1) // 和AppRoute中切换的tag值保持一致
            
            MineView()
                .tabItem { Label("我的", systemImage: "person") }
                .tag(2)
        }
    }
}

步骤5:配置Messages视图导航(可选)

如果需要跳转到消息页内部的子页面,将导航路径和全局路由绑定即可:

struct MessagesView: View {
    @EnvironmentObject var appRoute: AppRoute
    
    var body: some View {
        NavigationStack(path: $appRoute.messagesNavPath) {
            List {
                // 消息列表业务逻辑
            }
            .navigationTitle("消息")
            .navigationDestination(for: MessageDetailModel.self) { model in
                MessageDetailView(model: model)
            }
        }
    }
}

注意事项

  • 可在通知回调中先判断response.actionIdentifier或者通知的userInfo字段,按需执行不同跳转逻辑,避免所有通知点击都跳转到消息页
  • 如果项目最低支持iOS15及以下,使用NavigationView时可将NavigationPath替换为对应Bool类型的绑定变量控制导航弹出

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 07:45:04