我在 SwiftUI 中遇到過這個問題。當用戶按下按鈕時,我希望能夠從陣列中洗掉一個專案,但是當我嘗試時出現“執行緒 1:致命錯誤:索引超出范圍”錯誤。這似乎與 IntView 接受@Binding 的事實有關:如果我num只制作一個常規變數,則代碼可以正常作業而沒有錯誤。不幸的是,出于我的目的,我需要能夠將系結傳遞給視圖(這是一個簡化的情況),所以我不確定我需要做什么,這樣系結不會導致錯誤。
這是我的代碼:
import SwiftUI
struct IntView: View {
@Binding var num: Int // if I make this "var num: Int", there are no bugs
var body: some View {
Text("\(num)")
}
}
struct ArrayBugView: View {
@State var array = Array(0...10)
var body: some View {
ForEach(array.indices, id: \.self) { num in
IntView(num: $array[num])
Button(action: {
self.array.remove(at: num)
}, label: {
Text("remove")
})
}
}
}
任何幫助是極大的贊賞!
uj5u.com熱心網友回復:
在您的代碼中,ForEachwith indiciesandid: \.self是一個錯誤。SwiftUI 中的ForEachView 不像傳統的 for 回圈。國家的檔案ForEach:
/// It's important that the `id` of a data element doesn't change, unless
/// SwiftUI considers the data element to have been replaced with a new data
/// element that has a new identity.
這意味著我們不能在ForEach. ForEach必須在可識別專案的實際陣列上。這樣 SwiftUI 可以跟蹤移動的行視圖,這稱為結構標識,您可以在Demystify SwiftUI WWDC 2021中了解它。
因此,您必須將代碼更改為:
import SwiftUI
struct Item: Identifiable {
let id = UUID()
var num: Int
}
struct IntView: View {
let num: Int
var body: some View {
Text("\(num)")
}
}
struct ArrayView: View {
@State var array: [Item] = [Item(num:0), Item(num:1), Item(num:2)]
var body: some View {
ForEach(array) { item in
IntView(num: item.num)
Button(action: {
if let index = array.firstIndex(where: { $0.id == item.id }) {
array.remoteAt(index)
}
}, label: {
Text("remove")
})
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/437390.html
