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

SwiftUI导航问题:登录后无法从ProductFamilyView跳转至下一级视图

SwiftUI导航失效问题分析与修复

问题核心原因

你的导航失效是因为子视图中的navigationDestination没有被根NavigationStack识别:

  • 根NavigationStack仅在ContentView中定义,且只注册了跳转到ProductFamilyView的目的地。
  • ProductFamilyView、PartNumberView中的.navigationDestination属于子视图层级的修饰符,SwiftUI无法将这些目的地关联到根NavigationStack,导致点击NavigationLink时系统找不到对应的跳转目标,自然没有任何反应。
  • 虽然你使用了共享的NavigationModel管理NavigationPath,但navigationDestination的注册必须直接挂载在NavigationStack的视图链下,否则路径变化无法触发导航。

修复方案

方案一:统一在根NavigationStack注册所有目的地

将所有需要导航的目的地统一注册到ContentView的根NavigationStack中,同时移除子视图中的.navigationDestination修饰符:

修改ContentView的代码:

struct ContentView: View {
    
    @EnvironmentObject var navModel : NavigationModel
    @State private var navigated = false
    
    var body: some View {
        
        NavigationStack(path: $navModel.path) {
            Button(action: {
                self.navigated.toggle()
            }, label: {
                Text("LOGIN")
                    .bold()
                    .padding()
                    .foregroundColor(.white)
                    .background(
                        Capsule()
                            .foregroundColor(.green)
                            .frame(width: 200, height: 50)
                    )
            })
            // 登录跳转目的地
            .navigationDestination(isPresented: $navigated) {
                ProductFamilyView()
            }
            // 注册产品家族跳转目的地
            .navigationDestination(for: ProductFamilyModel.self) { productFamily in
                PartNumberView(productFamily: productFamily)
            }
            // 注册产品详情跳转目的地
            .navigationDestination(for: ProductModel.self) { partDetail in
                PartNumberRow(productDetail: partDetail)
            }
        }
        .environmentObject(navModel)
    }
}

移除ProductFamilyView中的以下代码:

.navigationDestination(for: ProductFamilyModel.self) { productFamily in
    PartNumberView(productFamily: productFamily)
}

移除PartNumberView中的以下代码:

.navigationDestination(for: ProductModel.self) { partDetail in
    PartNumberRow(productDetail: partDetail)
}

方案二:优化数据模型(可选,提升稳定性)

当前ProductFamilyModel和ProductModel是class类型,虽然实现了Hashable,但SwiftUI的导航系统对值类型(struct)的支持更稳定,建议将这两个类改为结构体:

// 改为struct
struct ProductFamilyModel: Identifiable, Hashable {
    var id = UUID().uuidString
    var name : String
    var partNumbers : [ProductModel] // 去掉可选类型,loadData返回的都是非空数据
    
    init(name: String) {
        self.name = name
        self.partNumbers = []
    }
    
    // 保留原loadData方法
    static func loadData() -> [ProductFamilyModel] {
        let productFamilyNames = ["Product Family 1",
                                  "Product Family 2",
                                  "Product Family 3"]
        let partDetails = ProductModel.loadData()
        var productFamilies : [ProductFamilyModel] = []
        
        for productFamilyName in productFamilyNames {
            let productFamily = ProductFamilyModel(name: productFamilyName)
            for partDetail in partDetails {
                if partDetail.productFamily == productFamilyName {
                    productFamily.partNumbers.append(partDetail)
                }
            }
            productFamilies.append(productFamily)
        }
        return productFamilies
    }
}

// 改为struct
struct ProductModel: Identifiable, Hashable {
    var id = UUID().uuidString
    var partNumber    : String
    var productFamily : String
    var description   : String
    
    init(model: Product) {
        self.partNumber    = model.partNumber
        self.productFamily = model.productFamily
        self.description   = model.description
    }
    
    // 保留原loadData方法
    static func loadData() -> Set<ProductModel> {
        let productDetails : Set<ProductModel> = [
            ProductModel(model: Product(
                partNumber: "100-1111-101",
                productFamily: "Product Family 1",
                description: "Part Number 100-1111-101"
            )),
            ProductModel(model: Product(
                partNumber: "100-1111-102",
                productFamily: "Product Family 1",
                description: "Part Number 100-1111-102"
            )),
            ProductModel(model: Product(
                partNumber: "100-1111-103",
                productFamily: "Product Family 1",
                description: "Part Number 100-1111-103"
            )),
            ProductModel(model: Product(
                partNumber: "200-1111-101",
                productFamily: "Product Family 2",
                description: "Part Number 200-1111-101"
            )),
            ProductModel(model: Product(
                partNumber: "200-1111-102",
                productFamily: "Product Family 2",
                description: "Part Number 200-1111-102"
            )),
            ProductModel(model: Product(
                partNumber: "200-1111-103",
                productFamily: "Product Family 2",
                description: "Part Number 200-1111-103"
            )),
            ProductModel(model: Product(
                partNumber: "300-1111-101",
                productFamily: "Product Family 3",
                description: "Part Number 300-1111-101"
            )),
            ProductModel(model: Product(
                partNumber: "300-1111-102",
                productFamily: "Product Family 3",
                description: "Part Number 300-1111-102"
            )),
            ProductModel(model: Product(
                partNumber: "300-1111-103",
                productFamily: "Product Family 3",
                description: "Part Number 300-1111-103"
            ))
        ]
        return productDetails
    }
}

同时修改PartNumberView中partDetails的定义,因为productFamily.partNumbers不再是可选数组:

// 原代码
// let partDetails = productFamily.partNumbers.compactMap( {$0} )
// 修改为
let partDetails = productFamily.partNumbers

补充说明

  • 多登录视图场景下,只需在根NavigationStack下注册所有登录流程和后续主流程的导航目的地即可,无需为每个登录视图单独创建NavigationStack。
  • 你实现的popToRoot()方法逻辑正确,配合共享NavigationModel可以实现跨视图的根导航控制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 18:50:42