簡體   English   中英

嘗試刪除最后一個元素時,帶有子項的 SwiftUI (2.0) 列表崩潰

[英]SwiftUI (2.0) list with children crashes when trying to delete the last element

我有以下代碼用於帶有孩子的 SwiftUI 列表,改編自另一個 StackOverflow 答案:

SwiftUI 2.0 帶孩子的列表 - 如何使披露按鈕的可點擊區域覆蓋整個列表項

struct ContentView: View {

    @EnvironmentObject var goodies: GlobalGoodies
    
    func listItem(for item: User) -> some View {
        Text(item.name)
    }
    
    var body: some View {
        NavigationView {
            List {
                ForEach(Array(goodies.users.enumerated()), id: \.1.id) { i, group in
                    DisclosureGroup(isExpanded: $goodies.users[i].isExpanded) {
                        ForEach(group.children ?? []) { item in
                            listItem(for:item)
                        }
                        .opacity(goodies.users[i].opacity)
                    } label: {
                        listItem(for: group)
                        .contentShape(Rectangle())
                        .onTapGesture {
                            withAnimation {
                                goodies.users[i].opacity = goodies.users[i].isExpanded ? 0.0 : 1.0
                                goodies.users[i].isExpanded.toggle()
                            }
                        }
                    }
                }
                .onDelete(perform: delete)
            }
        }
    }

    func delete(at offsets: IndexSet) {
        goodies.users.remove(atOffsets: offsets)
    }
}

GlobalGoodies class 和用戶 class 的源代碼,改編自HackingWithSwift教程示例。

struct User: Identifiable {
    let id = UUID()
    var name: String
    var children: [User]? = nil
    
    var isExpanded = false
    var opacity = 0.0
}

class GlobalGoodies: ObservableObject {
    @Published var users = [
        User(name: "Paul", children: [
            User(name: "Jenny")
        ]),
        User(name: "Taylor", children: [
            User(name: "Tyler"),
            User(name: "Luna")
        ]),
        User(name: "Adele", children: nil)
    ]
}

我能夠正常查看這些元素,並且可以毫無問題地刪除兩個(父)項目。 但是,當我嘗試刪除列表中最后一個剩余的(父)元素時,應用程序崩潰並顯示以下消息:

Fatal error: Index out of range: file Swift/ContiguousArrayBuffer.swift, line 444

我知道其他人在使用List時遇到了相同消息的類似錯誤,但僅在使用此特定設置顯示可擴展子元素時才會出現此錯誤。 我遵循了上面提到的 HackingWithSwift 教程的代碼(這只是一個普通的線性列表),我可以毫無問題地刪除其中的所有元素。

我試過使用新的List(children:)但是由於某種原因我無法添加onDelete

任何查明此錯誤位置的幫助都會很棒,因為我嘗試放置斷點等以查看 go 錯誤的地方。 該元素名義上被刪除,但崩潰似乎發生在調用body期間或之后。

提前感謝您的幫助!

經過更多的探索,我似乎已經能夠自己弄清楚這一點。 此行發生了超出范圍的錯誤:

DisclosureGroup(isExpanded: $goodies.users[i].isExpanded) {

(我可以通過替換為.constant(true)來阻止崩潰。)

我能夠通過使用 function 來解決這個問題,它在給定索引i的情況下提供自定義綁定,它在訪問它之前檢查索引是否在范圍內:

func binding(for index: Int) -> Binding<Bool> {
        Binding<Bool>(
            get: {
                if index > goodies.users.count - 1{
                    return false
                }
                return goodies.users[index].isExpanded
            },
            set: {
                if index > goodies.users.count - 1 {
                    // do nothing
                } else {
                    goodies.users[index].isExpanded = $0
                }
            }
        )
}

受影響線路的用法:

DisclosureGroup(isExpanded: binding(for: i)) {

這解決了崩潰問題。 之前有點難以確定,因為我沒有意識到在刪除列表項后訪問了綁定。 希望這對同一 position 中的人有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM