Swift中自定义视图的List选中功能失效问题排查
解决SwiftUI List自定义结构体项选中失效问题
问题原因
你的testData结构体虽然遵循了Hashable,但Swift自动合成的Equatable/Hashable实现会对比所有存储属性(name和id)。而你在List中指定了id: \.id,意味着List通过id识别行,但选中时SwiftUI需要匹配数据源中的testData实例与selection绑定的实例是否相等。由于默认的相等性判断同时检查name和id,导致实例匹配失败,选中功能完全失效。
解决方法
手动实现Hashable和Equatable,让判断仅基于唯一标识id,同时将id改为不可变的let类型,避免后续被意外修改:
struct testData: Hashable { var name = "" let id = UUID() // 改为let,保证标识唯一性 // 仅基于id判断相等性 static func == (lhs: testData, rhs: testData) -> Bool { lhs.id == rhs.id } // 仅基于id生成哈希值 func hash(into hasher: inout Hasher) { hasher.combine(id) } }
修改后,ListTest2的选中功能即可正常工作,底部文本也会正确显示选中项的名称。
补充说明
如果是在iOS平台开发,List的单选项选中默认需要开启编辑模式才能生效,可以通过添加工具栏按钮实现:
struct ListTest2: View { @State private var selection: testData? @State private var isEditing = false let names = [ testData(name: "Cyril"), testData(name: "Lana"), testData(name: "Mallory"), testData(name: "Sterling") ] var body: some View { NavigationStack { VStack { List(names, id: \.id, selection: $selection) { contact in Text(contact.name) } .navigationTitle("Contacts") .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button(isEditing ? "Done" : "Edit") { isEditing.toggle() } } } .environment(\.editMode, .constant(isEditing ? .active : .inactive)) Text("\(selection?.name ?? "N/A")") } } } }
根据你第一个示例的运行表现,推测你是在macOS环境下开发,该平台的List默认支持点击选中,无需额外开启编辑模式。
内容的提问来源于stack exchange,提问作者Andrew Voelkel
相关产品推荐
相关产品推荐

