iOS16中SwiftUI NavigationView已弃用,Form适配新写法遇报错求助
iOS 16+ SwiftUI 导航适配错误修复
问题根源
你遇到的「向不接受闭包的视图传递闭包」错误,是因为**navigationDestination被错误地放在了background修饰符内部**——这个修饰符仅接受视图类型,而你嵌套了带闭包的navigationDestination,导致类型不匹配。另外,iOS 16+的新导航API(NavigationStack+navigationDestination)逻辑和旧版NavigationView完全不同,不能直接照搬旧代码的嵌套结构。
修正步骤
1. 替换NavigationView为NavigationStack
iOS 16+必须用NavigationStack替代已弃用的NavigationView,如果需要基于选择值跳转,给NavigationStack传入selection绑定。
2. 调整navigationDestination的层级
navigationDestination需要直接附加在NavigationStack的子视图层级上(比如Form的外部),而不是单个按钮的背景里。它的作用是声明「当某个值被选中时,跳转到对应的视图」。
3. 简化按钮跳转逻辑
不需要用background嵌套隐藏的NavigationLink,直接通过按钮修改selection的值,navigationDestination会自动响应跳转。
修正后的完整代码
// 外层包裹NavigationStack,传入selection绑定 NavigationStack(selection: $selection) { Form { Section(header: Text("Settings")) { Toggle(isOn: $allowEmailNotifications) { Text("Ok to Email Tee Times, etc.") .font(stateManager.myNormalHNFont) } .padding() .onChange(of: allowEmailNotifications) { newValue in me.okToSendEmail = newValue } } Section(header: Text("Utilities")) { Button { self.selection = "ClaimMyRounds" } label: { Text("Consolidate My Rounds To This Account") .font(stateManager.myNormalHNFont) } .padding() .buttonStyle(BorderlessButtonStyle()) } } // 将navigationDestination放在Form外层,属于NavigationStack的子视图层级 .navigationDestination(for: String.self) { value in if value == "ClaimMyRounds" { PlayerMigrationView() } } }
额外优化(可选)
如果跳转逻辑有多个目标,建议用枚举替代String作为selection的类型,类型更安全:
// 定义跳转目标枚举 enum NavigationTarget: Hashable { case claimMyRounds // 可添加其他目标,比如case settingsDetail等 } // 修改selection的类型为NavigationTarget @State private var selection: NavigationTarget? = nil // 对应调整后的导航代码: NavigationStack(selection: $selection) { Form { // ... 其他代码不变 Section(header: Text("Utilities")) { Button { self.selection = .claimMyRounds } label: { Text("Consolidate My Rounds To This Account") .font(stateManager.myNormalHNFont) } .padding() .buttonStyle(BorderlessButtonStyle()) } } .navigationDestination(for: NavigationTarget.self) { target in switch target { case .claimMyRounds: PlayerMigrationView() } } }
内容的提问来源于stack exchange,提问作者phil
相关产品推荐
相关产品推荐

