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

SwiftUI:NavigationStack编程式添加不同类型子视图的问题

SwiftUI NavigationStack 使用通用 NavigationPath 无法传递数据到深层子视图的解决方案

问题场景与代码实现

父视图代码

struct MainDatabaseView: View {
@State private var path = NavigationPath()

var body: some View {
    NavigationStack(path: $path) {
        List {
            Section {
                NavigationLink(destination: MainTabPilotDatabaseView(path: $path)) {
                    Label("Pilots", systemImage: "person.2")
                        .foregroundStyle(.primary)
                }

                NavigationLink(destination: MainTabAircraftDatabaseView()) {
                    Label("Aircraft", systemImage: "airplane.circle")
                        .foregroundStyle(.primary)
                }
                
            } header: {
                Text("Database")
            }
        }
    }
}

子视图代码

struct MainTabPilotDatabaseView: View {
    @EnvironmentObject var pilotVM: PilotVM

    @Binding var path : NavigationPath

    var body: some View {
        List {
            ForEach(pilotVM.filteredPilots, id: \.id) { pilot in
                NavigationLink {
                    PilotDatabaseDetailView(pilot: pilot)
                } label: {
                    PilotCell(pilot: pilot, isInDetailView: false)
                        .contentShape(Rectangle())
                        .swipeActions(edge: .trailing) { delete(for: pilot) }
                        .swipeActions(edge: .leading) { markFavorite(for: pilot) }
                }
            }
        }
    
        .toolbar {
            ToolbarItem(placement: .topBarTrailing) { addPilot() }
        }
    }

    func addPilot() -> some View {
        Button {
            let pilotModelInput = PilotModelInput()
            let new = pilotVM.addPilotToModel(input: pilotModelInput)
            path.append(new)
        } label: {
            Image(systemName: "plus.circle.fill")
        }
      
    }
}

问题描述

当path定义为@State var path: [PilotEntity] = []时,点击子视图中的“plus.circle.fill”按钮可正常在NavigationStack中推入子子视图。但由于需要在NavigationStack中同时支持AircraftEntity类型,必须改用通用的NavigationPath,改用后无法将数据传递到子子视图,寻求最佳解决方式。

可行解决方案(编辑补充)

通过以下方式实现后可解决问题:

import SwiftUI

enum DatabaseTabOption {
    case pilot, aircraft
}

class NavigationStackManager: ObservableObject {
    @Published var path = NavigationPath()
}

struct MainDatabaseView: View {
    @StateObject var pathManager = NavigationStackManager()

    var body: some View {
        NavigationStack(path: $pathManager.path) {
            List {
                Section {
                    NavigationLink(value: DatabaseTabOption.pilot) {
                        Button {
                            pathManager.path.append(DatabaseTabOption.pilot)
                        } label: {
                            Label("Pilots", systemImage: "person.2")
                        }
                    }

                    NavigationLink(value: DatabaseTabOption.aircraft) {
                        Button {
                            pathManager.path.append(DatabaseTabOption.aircraft)
                        } label: {
                            Label("Aircraft", systemImage: "airplane.circle")
                        }
                    }
                } header: {
                    Text("Database")
                }
            }
            .navigationDestination(for: DatabaseTabOption.self, destination: { value in
                switch value {
                case .pilot:
                    MainTabPilotDatabaseView()
                        .environmentObject(pathManager)
                case .aircraft:
                    MainTabAircraftDatabaseView()
                        .environmentObject(pathManager)
                }
            })
        }
    }
}

实现思路:

  • 定义枚举DatabaseTabOption作为导航的标识类型
  • 创建NavigationStackManager类统一管理NavigationPath,通过@Published发布路径变化
  • 父视图中使用NavigationLink(value:)结合navigationDestination(for:destination:)关联导航目标
  • 将Button包裹在NavigationLink中保留导航箭头提示
  • 通过environmentObject将路径管理器传递给子视图,子视图即可向path添加任意类型的数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 17:02:51