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

SwiftUI中使用.navigationLink样式的Picker导致CPU占用100%

解决NavigationStack中使用.navigationLink样式Picker导致CPU占用100%的问题

在NavigationStack的子视图中使用.pickerStyle(.navigationLink)样式的Picker时,点击Picker会触发CPU占用率飙升至100%,界面完全无响应,切换为其他Picker样式(如.menu或.inline)则不会出现此问题。

问题原因

该问题源于.navigationLink样式的Picker与NavigationStack的导航逻辑存在冲突:当使用.constant()作为Picker的选择绑定时,SwiftUI的视图刷新机制会出现异常,引发无限循环的视图重绘或导航栈处理操作,最终耗尽CPU资源。

解决方案

方案1:使用@State变量替代常量绑定

将Picker的选择绑定从.constant("work")改为使用SwiftUI的@State状态变量,符合框架的状态管理规范,避免异常刷新。

修正后的完整代码:

import SwiftUI

struct Contact : Hashable, Identifiable {
    var id: String = ""
    var name: String = ""
    static var preview : [Contact] = [
        Contact(id: UUID().uuidString, name: "John"),
        Contact(id: UUID().uuidString, name: "Mary")
    ]
}

struct ContentView: View {
    let types : [String] = ["work","home"]
    @State private var selectedType = "work"
    
    var body: some View {
        NavigationStack(){
            List(Contact.preview){ contact in
                NavigationLink(contact.name, value: contact)
            }
            .navigationDestination(for: Contact.self){ contact in
                Form{
                    Picker(selection: $selectedType, label: Text("Type")){
                        ForEach(types, id: \.self) { item in
                            Text(item)
                        }
                    }
                    .pickerStyle(.navigationLink)
                }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

方案2:手动模拟导航链接式选择器

如果方案1仍存在问题,可以完全自定义导航链接的行为,绕过系统Picker的冲突逻辑:

// 在Contact的详情Form中替换原Picker代码
@Environment(\.dismiss) private var dismiss
@State private var selectedType = "work"

NavigationLink {
    List(types, id: \.self) { item in
        Button(action: {
            selectedType = item
            dismiss()
        }) {
            HStack {
                Text(item)
                Spacer()
                if item == selectedType {
                    Image(systemName: "checkmark")
                        .foregroundColor(.accentColor)
                }
            }
        }
    }
    .navigationTitle("Type")
} label: {
    HStack {
        Text("Type")
        Spacer()
        Text(selectedType)
            .foregroundColor(.secondary)
    }
}

说明

方案1是最直接的修复方式,通过遵循SwiftUI的状态管理原则解决冲突;方案2则提供了完全可控的自定义实现,适用于对UI有特殊需求或系统Picker存在兼容性问题的场景。

内容的提问来源于stack exchange,提问作者Ludovic C

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 19:10:30