如何在SwiftUI Table中展示字典?解决元素适配Identifiable问题
SwiftUI Table 展示字典的解决方法
我尝试用SwiftUI的Table组件展示字典数据时遇到了编译错误:
Type 'Dictionary<String, String>.Element' (aka '(key: String, value: String)') cannot conform to 'Identifiable'
原因是Table要求数据源元素要么遵循Identifiable协议,要么通过指定id参数来唯一标识元素——而字典的元素是(key, value)元组,既不遵循Identifiable,我一开始也没找到给Table指定id的方式(不像List那样直观)。原代码如下:
@State var dic: [String : String] = [ "name" : "Tim", "company" : "Apple" ] Table(dic.map{$0}.sorted{ $0.key < $1.key }) { TableColumn("Name") { item in Text(item.key) } TableColumn("Value") { item in TextField("", text: $item.value) } }
下面提供两种可行的解决方式:
方式一:用结构体包装字典元素
元组无法直接遵循协议,所以我们可以定义一个遵循Identifiable的结构体来封装key和value,利用字典key的唯一性作为id:
struct KeyValuePair: Identifiable { let id: String var value: String init(key: String, value: String) { self.id = key self.value = value } } // 视图内代码 @State var dic: [String : String] = [ "name" : "Tim", "company" : "Apple" ] @State private var pairs: [KeyValuePair] = [] init() { let initialPairs = dic.map { KeyValuePair(key: $0.key, value: $0.value) } .sorted { $0.id < $1.id } _pairs = State(initialValue: initialPairs) } var body: some View { Table(pairs) { TableColumn("Name") { item in Text(item.id) } TableColumn("Value") { item in TextField("", text: $item.value) .onChange(of: item.value) { newValue in dic[item.id] = newValue } } } }
方式二:使用带id参数的Table初始化器
其实SwiftUI的Table有支持非Identifiable数据源的初始化器,直接指定元组的key作为唯一标识即可:
@State var dic: [String : String] = [ "name" : "Tim", "company" : "Apple" ] var body: some View { let sortedItems = dic.map{$0}.sorted{ $0.key < $1.key } Table(sortedItems, id: \.key) { TableColumn("Name") { item in Text(item.key) } TableColumn("Value") { item in // 元组元素不可直接绑定,需自定义Binding同步修改到字典 TextField("", text: Binding( get: { dic[item.key] ?? "" }, set: { dic[item.key] = $0 } )) } } }
关键注意事项
- 方式二中不能直接绑定
$item.value,因为元组是值类型且元素不可变,必须通过自定义Binding将修改同步回原字典。 - 两种方式都需要处理数据同步,确保TextField的输入能更新到原始字典中。
内容的提问来源于stack exchange,提问作者Yiming Designer
相关产品推荐
相关产品推荐

