我有一个应用
分别提取数组的每个元素(通过索引) 然后将其绑定到可以利用单个元素的结构(查看和编辑)
但是每次数组减小大小时,都会导致索引超出范围错误,这不是直接由于我的代码而引起的
据我所知,这是因为:在用更改后的数组刷新循环之后,在某种程度上创建的视图还没有完全删除,仍然尝试访问超出范围的部分。但这就是我自己能想到的
这是我的示例代码:
import SwiftUI struct test: View { @State var TextArray = ["A","B","C"] var body:some View { VStack{ ForEach(TextArray.indices, id: \.self){index in //Text View TextView(text: self.$TextArray[index]) .padding() } //Array modifying button Button(action: { self.TextArray = ["A","B"] }){ Text(" Shrink array ") .padding() } } } } struct TextView:View { @Binding var text:String var body:some View { Text(text) } } #if DEBUG struct test_Previews: PreviewProvider { static var previews: some View { test() } } #endif
有没有更好的方法可以满足上述两个要求而又不引起此问题,或者有什么方法可以避免此问题?任何答复都表示赞赏。
终于了解了我遇到的那个问题的来龙去脉。
问题是建筑。它是2折:
以下代码之所以有效,是因为它循环遍历了唯一的事实来源,而没有进行复制,并且总是更新唯一的事实来源。自从您最初将其作为绑定传递以来,我什至还添加了一种方法来更改子视图中的字符串,我想您想在某个时候进行更改
import SwiftUI class DataSource: ObservableObject { @Published var textArray = ["A","B","C"] } struct Test: View { @EnvironmentObject var data : DataSource var body:some View { VStack{ ForEach(self.data.textArray , id: \.self) {text in TextView(text: self.data.textArray[self.data.textArray.firstIndex(where: {text == $0})!]) .padding() } //Array modifying button Button(action: { self.data.textArray.removeLast() }){ Text(" Shrink array ") .padding() } } } } struct TextView:View { @EnvironmentObject var data : DataSource var text:String var body:some View { VStack { Text(text) Button(action: { let index = self.data.textArray.firstIndex(where: {self.text == $0})! self.data.textArray[index] = "Z" }){ Text("Change String ") .padding() } } } } #if DEBUG struct test_Previews: PreviewProvider { static var previews: some View { Test().environmentObject(DataSource()) } } #endif