iOS 14.3中数组为空时崩溃



当数组为空时,我试图显示一些占位符数据。这在iOS 13.7中有效,但在iOS 14.3中发生了变化,所以当最后一个项目被删除时,你会出现崩溃:

致命错误:索引超出范围:Swift/ContiqueArrayBuffer.Swift文件,第444行

如果我注释掉testStore.data.isEmpty并只返回Form,我不会崩溃。

在iOS 14.3中数组为空时,如何显示占位符?

struct Test: Identifiable {
var text: String
var id: String { text }
}
extension Test {
final class Store: ObservableObject {
@Published var data = [Test(text: "Hi"), Test(text: "Bye")]
}
}
struct TestList: View {

@EnvironmentObject var testStore: Test.Store

var body: some View {
Group {
if testStore.data.isEmpty {
Text("Empty")
} else {
Form {
ForEach(testStore.data.indices, id: .self) { index in
TestRow(test: $testStore.data[index], deleteHandler: { testStore.data.remove(at: index) })
}
}
}
}
}
}
struct TestRow: View {

@Binding var test: Test
let deleteHandler: (() -> ())

var body: some View {
HStack {
Text(test.text)
.font(.headline)
Spacer()
Button(action: deleteHandler, label: Image(systemName: "trash"))
}
}
}

您可以使用此处提出的扩展:

struct Safe<T: RandomAccessCollection & MutableCollection, C: View>: View {
typealias BoundElement = Binding<T.Element>
private let binding: BoundElement
private let content: (BoundElement) -> C
init(_ binding: Binding<T>, index: T.Index, @ViewBuilder content: @escaping (BoundElement) -> C) {
self.content = content
self.binding = .init(get: { binding.wrappedValue[index] },
set: { binding.wrappedValue[index] = $0 })
}
var body: some View {
content(binding)
}
}

然后,如果你也想保留ForEach而不是List,你可以这样做:

struct TestList: View {
@EnvironmentObject var testStore: Test.Store
var body: some View {
Group {
if testStore.data.isEmpty {
Text("Empty")
} else {
Form {
ForEach(testStore.data.indices, id: .self) { index in
Safe($testStore.data, index: index) { binding in
TestRow(test: binding, deleteHandler: { testStore.data.remove(at: index) })
}
}
}
}
}
}
}

最新更新