iOS16下Swift用NavigationLink(value:label:)替换废弃API的方法
原有需求
- 点击按钮时调用
somethingElse()方法 - 点击后跳转至
SecondView()视图
原有代码
struct PrimaryView: View { @State var buttonSelected: Int? = nil func onSubmit() { somethingElse() self.buttonSelected = 1 } var body: some View { NavigationStack { NavigationLink(destination: SecondView(), tag: 1, selection: $buttonSelected) { Button(action: { onSubmit() }) { Text("Click me") } } } } }
收到的过时警告
'init(destination:tag:selection:label:)' was deprecated in iOS 16.0:
use NavigationLink(value:label:) inside a List within a
NavigationStack or NavigationSplitView...
重构方案
方案一:使用NavigationPath+枚举(推荐,支持多跳转场景扩展)
这种方式通过NavigationPath管理导航栈,配合枚举定义跳转目标,具备更好的类型安全性和扩展性:
struct PrimaryView: View { // 枚举定义所有可能的跳转目标,清晰直观 enum NavTarget { case secondView } @State private var navPath = NavigationPath() func onSubmit() { somethingElse() // 将跳转目标加入导航路径,触发跳转 navPath.append(NavTarget.secondView) } var body: some View { NavigationStack(path: $navPath) { Button(action: onSubmit) { Text("Click me") } // 绑定跳转值与对应视图 .navigationDestination(for: NavTarget.self) { target in switch target { case .secondView: SecondView() } } } } // 业务方法,按实际需求实现 func somethingElse() { // 这里写你的业务逻辑 } } // 示例目标视图 struct SecondView: View { var body: some View { Text("Second View") } }
方案二:使用布尔值绑定(适合单一跳转场景)
如果只有这一个跳转需求,用布尔值控制跳转的写法更简洁:
struct PrimaryView: View { @State private var shouldGoToSecondView = false func onSubmit() { somethingElse() shouldGoToSecondView = true } var body: some View { NavigationStack { Button(action: onSubmit) { Text("Click me") } // 通过isPresented绑定布尔值控制跳转 .navigationDestination(isPresented: $shouldGoToSecondView) { SecondView() } } } func somethingElse() { // 业务逻辑实现 } }
改动说明
- 移除了过时的
NavigationLink(destination:tag:selection:label:)初始化方法 - 完整保留原有逻辑:先执行
somethingElse(),再触发视图跳转 - 采用iOS16+推荐的
navigationDestinationAPI配合NavigationStack实现导航,符合Apple最新的导航框架设计
内容的提问来源于stack exchange,提问作者Timo Ernst
相关产品推荐
相关产品推荐

