【发布时间】:2020-07-24 18:08:27
【问题描述】:
SwiftUI 似乎有一个相当烦人的限制,这使得在获取每个元素的绑定以传递给子视图时很难创建 List 或 ForEach。
我见过的最常见的建议方法是迭代索引,并获得与$arr[index] 的绑定(事实上,当他们删除Binding 与Collection 的一致性时,类似的东西是suggested by Apple) :
@State var arr: [Bool] = [true, true, false]
var body: some View {
List(arr.indices, id: \.self) { index in
Toggle(isOn: self.$arr[index], label: { Text("\(idx)") } )
}
}
这工作直到数组的大小发生变化,然后它因索引超出范围运行时错误而崩溃。
这是一个会崩溃的例子:
class ViewModel: ObservableObject {
@Published var arr: [Bool] = [true, true, false]
init() {
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
self.arr = []
}
}
}
struct ContentView: View {
@ObservedObject var vm: ViewModel = .init()
var body: some View {
List(vm.arr.indices, id: \.self) { idx in
Toggle(isOn: self.$vm.arr[idx], label: { Text("\(idx)") } )
}
}
}
什么是处理从列表中删除的正确方法,同时仍保持使用绑定修改其元素的能力?
【问题讨论】:
-
Xcode 12 / iOS 14 不会崩溃
-
@Asperi - 很有趣。感谢您的发现。不确定这是 Apple 有意修复还是其他原因
-
确实很有趣。如果您使用
List它不会崩溃,但如果您将List替换为具有相同签名的ForEach- 它会崩溃(xCode 12 Beta 5)