如何在 SwiftUI 中读出 Indexset 元素的值?

How to read out values of Indexset elements in SwiftUI?

我有一个非常简单的 ForEach List 并且使用 onDelete() 删除条目没有问题。但是,由于元素中的一个变量存储了文件的 url,我不想留下它,所以我希望通过 FileManager 实现清理。但对于我来说,我似乎无法访问实际的 url 以插入 FileManager 操作。

这是我得到的,以及相关的错误:

struct ListItem: Identifiable, Codable {
    let id = UUID()
    let name: String
    let fileurl: URL
}

class ItemList: ObservableObject {
    @Published var items: [ListItem] {
        didSet {
            let encoder = JSONEncoder()
            if let encoded = try? encoder.encode(items) {
                UserDefaults.standard.set(encoded, forKey: "Items")
            }
        }
    }
    
    init() {
        if let items = UserDefaults.standard.data(forKey: "Items") {
            let decoder = JSONDecoder()
            if let decoded = try? decoder.decode([ListItem].self, from: items) {
                self.items = decoded
                return
            }
        }
        
        self.items = []
    }
}

struct ItemListView: View {
    func getDocumentsDirectory() -> URL {
        return FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first!
    }
    @ObservedObject var itemlist = ItemList()
    var supportFolder: URL {
        return FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first!
    }
@EnvironmentObject var thingy: Thingy
    var body: some View {
        VStack {
            Spacer()
            Spacer()
            Spacer()
            
            List {
                ForEach(itemlist.items) { item in
                    HStack {
                        VStack(alignment: .leading) {
                            Text(item.name)
                                .font(.headline)
                            Text(item.fileurl.lastPathComponent)
                        }
                        .onTapGesture {
self.thingy.load(self.supportFolder.appendingPathComponent("/listfiles/\(item.fileurl.lastPathComponent)")) //No issues with item.fileurl here
                            print("Selected: \(item.fileurl)")
                        }
                    }
                }
                .onDelete(perform: removeItems)
                
            }.disabled(keyMissing)
                .navigationBarTitle("List files", displayMode: .large).accentColor(Color.blue)
                .navigationBarItems(trailing:
                    Button(action: {
                        …
                    }
                    ) {NavigationLink(…) {
                        Image(systemName: "plus")
                        }


                        
                    }
                                        
            )
            Button(…){…}  
        }
            
        .onAppear(perform: {…})
            .onDisappear(…)
    }
    
    
    //    MARK: below is the issue
    func removeItems(at offsets: IndexSet) {
        
   do {
            try FileManager.default.removeItem(atPath: (itemlist.items.fileurl).path)
            print("File is deleted")
        }
        catch { print("Couldn't delete file")} //This would be ideal, but doesn't work stating "Value of type '[ListItem]' has no member 'fileurl'"



    itemlist.items.remove(atOffsets: offsets) //This works fine
        
       
    }
}

理想情况下,我可以简单地插入项目 list.items.fileurl 但它的行为就像是未知的。

我也尝试过使用 list.items.description(和类似的)做一个巨大的解决方法,但是没有一致的方法来始终如一地提取输出字符串的正确部分。老实说,我感觉很奇怪,我无法访问文件 url 的值,我觉得我正盯着解决方案的脸看,但看不到它。

我也尝试简单地应用 onDelete()

中的逻辑

像这样:

.onDelete{
                    do {
                        try FileManager.default.removeItem(atPath: (binlist.items.fileloc).path)
                        print("File is deleted")
                    }
                    catch { print("Couldn't delete file")}
                }

但是这让我感到 Cannot convert value of type '() -> ()' to expected argument type 'Optional<(IndexSet) -> Void>'

我觉得这里有点格格不入,找不到这方面的好文档。

编辑:@Asperi 的解决方案对我有用,不敢相信我在发布之前就在盯着解决方案。

可以像下面这样

func removeItems(at offsets: IndexSet) {

    for i in offsets {
        do {
            try FileManager.default.removeItem(atPath: (itemlist.items[i].fileurl).path)
            print("File is deleted")
        }
        catch { print("Couldn't delete file")}
    }

    itemlist.items.remove(atOffsets: offsets) //This works fine
}