2

如何从失败的构建中纠正此代码?基本上想使用 ForEach 来遍历基于 [ customEnum : customStrut ] 的字典。

否则,如果这是有问题的实现 SwiftUI 支持的不同方法?

错误

在 'ForEach' 上引用初始化程序 'init(_:id:content:)' 要求 '[GCFilterViewOptions.FilterOptions : GCFilterViewOptions.FilterOptionValues]' 符合 'RandomAccessCollection'

类型'(key: GCFilterViewOptions.FilterOptions, value: GCFilterViewOptions.FilterOptionValues)' 不能符合'Hashable';只有结构/枚举/类类型可以符合协议

代码

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 
            }
        }
    }
}
4

2 回答 2

2

由于状态字典不是“随机访问”能力的集合,所以它不能直接在 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
    }
}
于 2020-04-26T12:49:58.517 回答
1

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),
]

如果您想使用字典(例如断言选项只列出一次),您应该保留当前的数据结构并只使用字典键来访问元素。请记住,字典没有排序,如果您想要一个稳定的顺序,您应该对其进行排序(例如使用键的 rawValue):

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: { $0.rawValue < $1.rawValue }) {
    let optionValue = filterSelection[key]!
    print(option, optionValue)
}

请注意,在 Swift 中,枚举情况与属性一样是小写的。newLine只有类型以大写字母 ( , not )开头NewLine

此外,枚举类型名称应该是单数的,因为在实例化时它们只代表一个选项。使用FilterOption而不是FilterOptions.

相同的filterSelections应该是单一的,因为选择已经包含多个元素。

于 2020-04-26T13:56:38.600 回答