具有@Binding控件的SwiftUI动态列表

时间:2019-09-07 19:48:36

标签: swiftui combine swiftui-list

如何使用@Binding驱动的控件构建动态列表,而不必手动引用数组?似乎很明显,但是使用List或ForEach遍历数组会产生各种奇怪的错误。

struct OrderItem : Identifiable {
    let id = UUID()
    var label : String
    var value : Bool = false
}

struct ContentView: View {
    @State var items = [OrderItem(label: "Shirts"),
                        OrderItem(label: "Pants"),
                        OrderItem(label: "Socks")]
    var body: some View {
        NavigationView {
            Form {
                Section {
                    List {
                        Toggle(items[0].label, isOn: $items[0].value)
                        Toggle(items[1].label, isOn: $items[1].value)
                        Toggle(items[2].label, isOn: $items[2].value)
                    }
                }
            }.navigationBarTitle("Clothing")
        }
    }
}

这不起作用:

            ...
                Section {
                    List($items, id: \.id) { item in
                        Toggle(item.label, isOn: item.value)
                    }
                }
            ...
  

类型“ _”没有成员“ id”

也没有:

            ...
                Section {
                    List($items) { item in
                        Toggle(item.label, isOn: item.value)
                    }
                }
            ...
  

无法推断出通用参数“ SelectionValue”

2 个答案:

答案 0 :(得分:4)

尝试类似

            ...
                Section {
                    List(items.indices) { index in
                        Toggle(self.items[index].label, isOn: self.$items[index].value)
                    }
                }
            ...

答案 1 :(得分:1)

虽然 Maki 的回答有效(在某些情况下)。它不是最佳的,它是 discouraged by Apple。相反,他们在 WWDC 2021 期间提出了 the following solution

<块引用>

只需将您的集合的绑定传递到列表中,使用 普通美元符号运算符,SwiftUI 将传回绑定到 闭包中的每个单独元素。

像这样:

struct ContentView: View {
    @State var items = [OrderItem(label: "Shirts"),
                        OrderItem(label: "Pants"),
                        OrderItem(label: "Socks")]

    var body: some View {
        NavigationView {
            Form {
                Section {
                    List($items) { $item in
                        Toggle(item.label, isOn: $item.value)
                    }
                }
            }.navigationBarTitle("Clothing")
        }
    }
}