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

SwiftUI中如何通过NavigationStack传参区分页面跳转来源?

解决NavigationStack中传递来源标识的问题

要区分进入页面C的来源,你可以通过给ViewOptions的caseC添加关联值来携带来源信息,具体实现如下:

步骤1:定义来源标识枚举

先新增一个枚举用来标记页面来源:

enum PageSource {
    case fromA
    case fromB
}

步骤2:修改ViewOptions枚举

给caseC添加关联值,接收PageSource类型的参数:

enum ViewOptions {
    case caseB
    case caseC(PageSource) // 新增关联值存储来源
    
    @ViewBuilder func view(_ path: Binding<NavigationPath>) -> some View{
        switch self{
        case .caseB:
            B(path: path)
        case .caseC(let source): // 取出关联的来源信息
            C(path: path, source: source) // 传递给C页面
        }
    }
}

步骤3:修改跳转逻辑

分别在A和B页面跳转C时,传入对应的来源标识:

  • A页面的跳转按钮:
Button {
    path.append(SampleApp.ViewOptions.caseC(.fromA))
} label: {
    Text("Go to C")
}
  • B页面的跳转按钮:
Button {
    path.append(SampleApp.ViewOptions.caseC(.fromB))
} label: {
    Text("Go to C")
}

步骤4:修改C页面接收来源参数

更新C页面,添加source属性,后续就可以根据这个值做区分逻辑:

struct C: View {
    @Binding var path: NavigationPath
    let source: PageSource // 接收来源参数
    
    var body: some View {
        VStack {
            Text("C")
            // 根据来源显示不同内容或执行逻辑
            switch source {
            case .fromA:
                Text("来自页面A")
            case .fromB:
                Text("来自页面B")
            }
        }
    }
}

完整修改后的代码

import SwiftUI

@main
struct SampleApp: App {
    
    @State private var path: NavigationPath = .init()
    
    var body: some Scene {
        WindowGroup {
            NavigationStack(path: $path){
                A(path: $path)
                    .navigationDestination(for: ViewOptions.self) { option in
                        option.view($path)
                    }
            }
        }
    }
    
    // 新增来源标识枚举
    enum PageSource {
        case fromA
        case fromB
    }
    
    enum ViewOptions {
        case caseB
        case caseC(PageSource)
        
        @ViewBuilder func view(_ path: Binding<NavigationPath>) -> some View{
            switch self{
            case .caseB:
                B(path: path)
            case .caseC(let source):
                C(path: path, source: source)
            }
        }
    }
}

struct A: View {
    @Binding var path: NavigationPath
    var body: some View {
        VStack {
            Text("A")
            Button {
                path.append(SampleApp.ViewOptions.caseB)
            } label: {
                Text("Go to B")
            }
            Button {
                path.append(SampleApp.ViewOptions.caseC(.fromA))
            } label: {
                Text("Go to C")
            }
        }
    }
}

struct B: View {
    @Binding var path: NavigationPath
    var body: some View {
        VStack {
            Text("B")
            Button {
                path.append(SampleApp.ViewOptions.caseC(.fromB))
            } label: {
                Text("Go to C")
            }
        }
    }
}

struct C: View {
    @Binding var path: NavigationPath
    let source: SampleApp.PageSource
    
    var body: some View {
        VStack {
            Text("C")
            switch source {
            case .fromA:
                Text("来自页面A")
            case .fromB:
                Text("来自页面B")
            }
        }
    }
}

这种方式利用Swift枚举的关联值特性,直接把来源信息嵌入到导航路径的参数中,既简洁又能准确传递上下文信息,完全符合NavigationStack的设计逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 00:25:19