You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 17:33:33