iOS 16:NavigationView迁移至NavigationStack的导航跳转问题
核心改造思路
iOS 16之后,NavigationView被NavigationStack替代,带tag和selection的NavigationLink初始化方法被废弃。要保留按钮触发跳转的逻辑,我们可以:
- 用路由枚举替代原来的Int类型tag,让跳转逻辑更清晰
- 使用
NavigationStack的.navigationDestination修饰符来匹配路由和目标页面 - 按钮直接设置路由值,触发对应页面跳转
改造后的完整代码
// 定义路由枚举,对应原来的tag值和目标页面 enum ProjectRoute: Hashable { case colourList(project: Project) case addImage case moreImages } struct YourView: View { let project: Project @State private var showImageMenu = false @State private var isShowCamera = false @State private var isShowPhotoLibrary = false // 用路由枚举替代原来的Int类型action变量 @State private var selectedRoute: ProjectRoute? var body: some View { // 替换NavigationView为NavigationStack,绑定路由变量 NavigationStack(path: $selectedRoute) { List { Group { Button(action: { showImageMenu = true }) { Text("New Title Image") } .confirmationDialog("Select Image Source", isPresented: $showImageMenu, titleVisibility: .visible) { Button("Take Photo") { isShowCamera = true } Button("Choose from Albums") { isShowPhotoLibrary = true } } Button(action: { selectedRoute = .moreImages NSLog("More Images") }) { Text("More Images (x)") } Button(action: { selectedRoute = .addImage NSLog("Add Image") }) { Text("Add Image") } Button(action: { selectedRoute = .colourList(project: project) NSLog("Colour List") }) { Text("Colour List") } } } // 统一管理路由与目标页面的对应关系 .navigationDestination(for: ProjectRoute.self) { route in switch route { case .colourList(let project): ProjectColourAddView(project: project) case .addImage: // 替换为你的Add Image目标页面 Text("Add Image Page") case .moreImages: // 替换为你的More Images目标页面 Text("More Images Page") } } } } }
关键说明
- 路由枚举:
ProjectRoute实现Hashable协议(NavigationStack的路径绑定要求),每个枚举case对应原来的一个tag,需要传参的页面(比如colourList)可以直接携带参数,类型更安全。 - NavigationStack绑定:通过
path: $selectedRoute绑定路由变量,当selectedRoute被设置为某个枚举值时,自动触发对应页面的跳转。 - navigationDestination:替代原来的隐藏NavigationLink,将路由与页面的对应逻辑集中管理,更符合iOS 16+的导航规范。
- 按钮逻辑:按钮的action直接设置
selectedRoute为对应枚举值,和原来设置action变量的逻辑完全一致,无需额外学习成本。
内容的提问来源于stack exchange,提问作者Ceri Turner
相关产品推荐
相关产品推荐

