SwiftUI中使用.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
相关产品推荐
相关产品推荐

