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

SwiftUI使用@EnvironmentObject路由跳转至条目详情视图无响应问题排查

问题原因

你的代码存在两个核心问题导致点击无响应:

  • 缺少导航容器:NavigationLink 必须在 NavigationStack(iOS 16及以上)或 NavigationView(iOS 15及更早)的层级内才能触发跳转逻辑,当前代码没有加任何导航容器包裹,所有导航相关操作都不会生效。
  • 视图结构语法错误:ContentView 的 body 属性内直接放置了 ForEach 和 Button 两个并列视图,没有用 VStack、List 这类布局容器包裹,代码本身存在编译错误,无法正常运行。
  • 可选优化项:PetView 中对 selectedPet 做了强制解包,当值为空时会直接触发应用崩溃,建议改为传参或可选绑定提升安全性。
修复方案

只需做两处修改即可实现预期效果:

  1. 给 ContentView 的内容外层依次添加导航容器、布局容器
  2. 可选优化 PetView 的参数传递逻辑,避免强制解包

最小改动修复示例(保留你原有的代码逻辑)

import SwiftUI

struct ContentView: View {
    @EnvironmentObject var viewRouter: ViewRouter

    var body: some View {
        // 加导航容器
        NavigationStack {
            // 加布局容器包裹并列子视图
            VStack(spacing: 16) {
                ForEach(viewRouter.pets) { pet in
                    NavigationLink(
                        destination: PetView(),
                        tag: pet,
                        selection: $viewRouter.selectedPet,
                        label: {
                            Text(pet.name)
                        }
                    )
                }
                
                Button("Go to first pet.") {
                    viewRouter.selectedPet = viewRouter.pets[0]
                }
            }
        }
    }
}

修改后点击条目或按钮即可正常跳转。

更规范的iOS 16+写法(推荐)

用 NavigationStack 的 path 绑定 + navigationDestination 修饰符实现,逻辑更清晰,也避免强制解包风险:

调整ViewRouter

class ViewRouter: ObservableObject {
    // 改成NavigationPath类型适配导航栈
    @Published var navPath = NavigationPath()
    @Published var pets: [Pet] = [Pet(name: "Louie"), Pet(name: "Fred"), Pet(name: "Stanley")]
}

调整ContentView

struct ContentView: View {
    @EnvironmentObject var viewRouter: ViewRouter
    
    var body: some View {
        NavigationStack(path: $viewRouter.navPath) {
            List {
                ForEach(viewRouter.pets) { pet in
                    NavigationLink(value: pet) {
                        Text(pet.name)
                    }
                }
                
                Button("Go to first pet") {
                    viewRouter.navPath.append(viewRouter.pets[0])
                }
            }
            .navigationDestination(for: Pet.self) { pet in
                PetView(pet: pet)
            }
            .navigationTitle("宠物列表")
        }
    }
}

调整PetView

struct PetView: View {
    // 直接接收参数,无需依赖ViewRouter拿值
    let pet: Pet
    
    var body: some View {
        Text(pet.name)
            .navigationTitle(pet.name)
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 07:36:04