如何在各新视图需选中状态时使用navigationDestination实现多级跳转?
SwiftUI多级导航跳转(带选中状态绑定)的实现方案
针对你遇到的多级跳转问题,这里提供几种可行的实现方式,核心是解决导航时如何正确传递donutBinding的问题:
方案一:统一路由枚举管理(推荐)
定义一个枚举来区分不同的导航目标,将需要的标识(如Donut.ID)包含在枚举关联值中,所有导航逻辑在根视图统一处理:
- 定义路由枚举:
enum NavigationRoute: Hashable { case donutEditor(Donut.ID) case donutDetail(Donut.ID) }
- 在根视图(ParentGrid)添加对应的
navigationDestination:
ParentGrid .navigationDestination(for: NavigationRoute.self) { route in switch route { case .donutEditor(let donutID): DonutEditor(donut: model.donutBinding(id: donutID)) case .donutDetail(let donutID): DetailViewPage2(donut: model.donutBinding(id: donutID)) } }
- 在DonutEditor中使用路由枚举跳转:
// DonutEditor视图内的跳转按钮 NavigationLink(value: NavigationRoute.donutDetail(donut.id)) { Text("跳转到详情页2") }
这种方式的优势是集中管理所有导航规则,后续新增页面只需扩展枚举即可,逻辑清晰且扩展性强。
方案二:子视图内独立处理导航
如果DonutEditor可以通过环境变量或直接引用拿到model实例,也可以在子视图内单独添加navigationDestination:
struct DonutEditor: View { @Binding var donut: Donut @EnvironmentObject var model: DonutModel // 假设model通过环境传递 var body: some View { // 编辑器内容... NavigationLink(value: donut.id) { Text("跳转到详情页2") } .navigationDestination(for: Donut.ID.self) { donutID in DetailViewPage2(donut: model.donutBinding(id: donutID)) } } }
这种方式适合每个子视图独立管理自身的导航目标,但需要确保model能被当前视图访问到。
方案三:绑定包装类型传递
如果不想使用枚举,可以定义一个包装Donut.ID的可哈希类型,间接传递绑定所需的标识:
- 定义包装类型:
struct DonutBindingWrapper: Hashable { let id: Donut.ID static func == (lhs: Self, rhs: Self) -> Bool { lhs.id == rhs.id } func hash(into hasher: inout Hasher) { hasher.combine(id) } }
- 根视图添加对应的导航目标:
ParentGrid .navigationDestination(for: Donut.ID.self) { donutID in DonutEditor(donut: model.donutBinding(id: donutID)) } .navigationDestination(for: DonutBindingWrapper.self) { wrapper in DetailViewPage2(donut: model.donutBinding(id: wrapper.id)) }
- DonutEditor内跳转:
NavigationLink(value: DonutBindingWrapper(id: donut.id)) { Text("跳转到详情页2") }
内容的提问来源于stack exchange,提问作者erotsppa
相关产品推荐
相关产品推荐

