iOS16+:Button结合NavigationStack调用NavigationLink的非废弃实现
核心思路
废弃的tag:selection:式NavigationLink可以用NavigationStack的路径绑定替代,通过先执行任务再更新导航路径的方式,确保任务完成后再触发跳转。推荐用枚举定义导航目的地,比原代码的字符串tag更安全、易维护。
完整迁移代码
// 定义枚举明确所有导航目的地,需遵循Hashable协议 enum NavigationDestination: Hashable { case view1 case notView1 } struct ContentView: View { // 用数组管理导航路径,替代原有的selection变量 @State private var path: [NavigationDestination] = [] var body: some View { NavigationStack(path: $path) { VStack(spacing: 20) { Button("先执行任务再跳转到View1") { // 执行耗时任务(示例为同步sleep,实际建议用异步操作) mySleepFunctionToSleepOneSecond() // 任务完成后,往路径数组添加目的地,触发导航 path.append(.view1) } Button("立即跳转到NotView1") { // 直接添加目的地触发跳转 path.append(.notView1) } } .navigationTitle("Navigation") // 绑定枚举值与对应目标视图 .navigationDestination(for: NavigationDestination.self) { destination in switch destination { case .view1: View1() case .notView1: NotView1() } } } } // 示例耗时函数 private func mySleepFunctionToSleepOneSecond() { Thread.sleep(forTimeInterval: 1) } } // 示例目标视图(需自行实现业务逻辑) struct View1: View { var body: some View { Text("View1") .navigationTitle("View1") } } struct NotView1: View { var body: some View { Text("NotView1") .navigationTitle("NotView1") } }
关键说明
- 枚举管理目的地:用
Hashable枚举替代字符串tag,避免拼写错误,同时让导航逻辑更直观 - 路径绑定机制:
NavigationStack(path: $path)通过绑定数组管理导航栈,向数组添加元素即触发对应跳转 - 目的地映射:
.navigationDestination(for:)负责将枚举值与目标视图关联,无需再写隐藏的EmptyView式NavigationLink - 任务执行优先级:按钮回调内先完成所有任务,再更新
path,确保导航动作在任务结束后触发,和原逻辑完全一致 - 异步任务处理:如果实际任务是异步操作(比如网络请求),需在主线程更新
path,示例:Button("异步任务后跳转") { Task { // 异步执行任务 await fetchData() // 回到主线程更新导航路径 DispatchQueue.main.async { path.append(.view1) } } }
内容的提问来源于stack exchange,提问作者BlowMyMind
相关产品推荐
相关产品推荐

