如何将 SwiftUI ForEach 与字典一起使用 [ customEnum : customStrut ] - 出现 "conform to 'RandomAccessCollection'" 错误
How use use SwiftUI ForEach with a dictionary [ customEnum : customStrut ] - getting "conform to 'RandomAccessCollection'" error
我怎样才能从失败的构建中更正此代码?基本上想使用 ForEach 遍历基于 [ customEnum : customStrut ] 的字典。
否则,如果这有问题,是否可以通过其他方式实现 SwiftUI 支持?
错误
Referencing initializer 'init(_:id:content:)' on 'ForEach' requires
that '[GCFilterViewOptions.FilterOptions :
GCFilterViewOptions.FilterOptionValues]' conform to
'RandomAccessCollection'
Type '(key: GCFilterViewOptions.FilterOptions, value:
GCFilterViewOptions.FilterOptionValues)' cannot conform to 'Hashable';
only struct/enum/class types can conform to protocols
代码
import SwiftUI
struct GCFilterViewOptions: View {
enum FilterOptions {
case NewLine
case Comma
case Space
}
struct FilterOptionValues {
var title : String
var selected : Bool
}
var filterSelections : [FilterOptions : FilterOptionValues] = [
FilterOptions.NewLine : FilterOptionValues(title: "New Line", selected: true),
FilterOptions.Comma : FilterOptionValues(title: "Comma", selected: true),
FilterOptions.Space : FilterOptionValues(title: "Space", selected: false)
]
var body : some View {
HStack {
ForEach(filterSelections, id:\.self) { filterOption in. // ** ERRORS HERE **
Text("TBD")
// Will be putting checkboxes here - i.e. so can chose which ones
}
}
}
}
由于 states 字典不是 "random access" 可收集的,因此不能直接在 ForEach 中使用,这里是可能的方法
HStack {
ForEach(Array(filterSelections.keys.enumerated()), id:\.element) { _, key in
Text("TBD \(self.filterSelections[key]?.title ?? "")")
// Will be putting checkboxes here - i.e. so can chose which ones
}
}
ForEach 循环仅支持支持 RandomAccess 的数据结构(Apple 关于什么是 RandomAccessCollection 的文档很棒)。
如果你真的不需要字典结构,你可以使用一个简单的结构。这与您的基本相同,但枚举嵌套在其中并且是 属性:
struct FilterOption {
enum FilterOptionType {
case newLine
case comma
case space
}
var type: FilterOptionType
var title: String
var selected: Bool
}
var filterSelection: [FilterOption] = [
FilterOption(type: .newLine, title: "New line", selected: true),
FilterOption(type: .comma, title: "Comma", selected: false),
FilterOption(type: .space, title: "Space", selected: true),
]
如果您希望使用字典(例如断言选项只列出一次),您应该保留当前的数据结构并仅使用字典键来访问元素。请记住,字典是无序的,如果你想要一个稳定的顺序,你应该对它进行排序(例如使用键的原始值):
enum FilterOption: String {
case newLine
case comma
case space
}
struct FilterOptionValue {
var title: String
var selected: Bool
}
var filterSelection: [FilterOption: FilterOptionValue] = [
.newLine: FilterOptionValue(title: "New Line", selected: true),
.comma: FilterOptionValue(title: "Comma", selected: true),
.space: FilterOptionValue(title: "Space", selected: false)
]
// Guarantees a stable print order
for option in filterSelection.keys.sorted(by: { [=11=].rawValue < .rawValue }) {
let optionValue = filterSelection[key]!
print(option, optionValue)
}
请注意,在 Swift 中,枚举大小写与属性一样都是小写的。只有类型以大写字母开头(newLine
,而不是 NewLine
)。
此外,枚举类型名称应该是单数的,因为在实例化时它们只代表一个选项。使用 FilterOption
而不是 FilterOptions
.
与 filterSelections
相同,应该是单数,因为选择已经包含多个元素。
我怎样才能从失败的构建中更正此代码?基本上想使用 ForEach 遍历基于 [ customEnum : customStrut ] 的字典。
否则,如果这有问题,是否可以通过其他方式实现 SwiftUI 支持?
错误
Referencing initializer 'init(_:id:content:)' on 'ForEach' requires that '[GCFilterViewOptions.FilterOptions : GCFilterViewOptions.FilterOptionValues]' conform to 'RandomAccessCollection'
Type '(key: GCFilterViewOptions.FilterOptions, value: GCFilterViewOptions.FilterOptionValues)' cannot conform to 'Hashable'; only struct/enum/class types can conform to protocols
代码
import SwiftUI
struct GCFilterViewOptions: View {
enum FilterOptions {
case NewLine
case Comma
case Space
}
struct FilterOptionValues {
var title : String
var selected : Bool
}
var filterSelections : [FilterOptions : FilterOptionValues] = [
FilterOptions.NewLine : FilterOptionValues(title: "New Line", selected: true),
FilterOptions.Comma : FilterOptionValues(title: "Comma", selected: true),
FilterOptions.Space : FilterOptionValues(title: "Space", selected: false)
]
var body : some View {
HStack {
ForEach(filterSelections, id:\.self) { filterOption in. // ** ERRORS HERE **
Text("TBD")
// Will be putting checkboxes here - i.e. so can chose which ones
}
}
}
}
由于 states 字典不是 "random access" 可收集的,因此不能直接在 ForEach 中使用,这里是可能的方法
HStack {
ForEach(Array(filterSelections.keys.enumerated()), id:\.element) { _, key in
Text("TBD \(self.filterSelections[key]?.title ?? "")")
// Will be putting checkboxes here - i.e. so can chose which ones
}
}
ForEach 循环仅支持支持 RandomAccess 的数据结构(Apple 关于什么是 RandomAccessCollection 的文档很棒)。
如果你真的不需要字典结构,你可以使用一个简单的结构。这与您的基本相同,但枚举嵌套在其中并且是 属性:
struct FilterOption {
enum FilterOptionType {
case newLine
case comma
case space
}
var type: FilterOptionType
var title: String
var selected: Bool
}
var filterSelection: [FilterOption] = [
FilterOption(type: .newLine, title: "New line", selected: true),
FilterOption(type: .comma, title: "Comma", selected: false),
FilterOption(type: .space, title: "Space", selected: true),
]
如果您希望使用字典(例如断言选项只列出一次),您应该保留当前的数据结构并仅使用字典键来访问元素。请记住,字典是无序的,如果你想要一个稳定的顺序,你应该对它进行排序(例如使用键的原始值):
enum FilterOption: String {
case newLine
case comma
case space
}
struct FilterOptionValue {
var title: String
var selected: Bool
}
var filterSelection: [FilterOption: FilterOptionValue] = [
.newLine: FilterOptionValue(title: "New Line", selected: true),
.comma: FilterOptionValue(title: "Comma", selected: true),
.space: FilterOptionValue(title: "Space", selected: false)
]
// Guarantees a stable print order
for option in filterSelection.keys.sorted(by: { [=11=].rawValue < .rawValue }) {
let optionValue = filterSelection[key]!
print(option, optionValue)
}
请注意,在 Swift 中,枚举大小写与属性一样都是小写的。只有类型以大写字母开头(newLine
,而不是 NewLine
)。
此外,枚举类型名称应该是单数的,因为在实例化时它们只代表一个选项。使用 FilterOption
而不是 FilterOptions
.
与 filterSelections
相同,应该是单数,因为选择已经包含多个元素。