简体   繁体   English

SwiftUI中List的.ondelete()如何添加确认

[英]How to add confirmation to .ondelete() of List in SwiftUI

How can I add a confirmation to my deleteRow() function?如何向我的deleteRow() function 添加确认信息? A already added the .alert but I don't know how to continue. A 已经添加了.alert但我不知道如何继续。

List {
    ForEach(data, id: \.self) { item in
        Text(item)
        .alert(isPresented: self.$showingDeleteAlert) {
            Alert(title: Text("..."), message: Text("..."), primaryButton: .destructive(Text("Delete")) {
                deleteRow // ???
                }, secondaryButton: .cancel()
            )
        }
    }
    .onDelete(perform: deleteRow)
}

func deleteRow(at indexSet: IndexSet) {
    for index in indexSet {
        let item = data[index]
        viewContext.delete(item)
        do {
            try viewContext.save()
        } catch let error {
            print("Error: \(error)")
        }
    }
}
``

Here is possible approach:这是可能的方法:

@State private var toBeDeleted: IndexSet?

...

List {
    ForEach(data, id: \.self) { item in
        Text(item)
        .alert(isPresented: self.$showingDeleteAlert) {
            Alert(title: Text("..."), message: Text("..."), primaryButton: .destructive(Text("Delete")) {
                    for index in self.toBeDeleted {
                        let item = data[index]
                        viewContext.delete(item)
                        do {
                            try viewContext.save()
                        } catch let error {
                            print("Error: \(error)")
                        }
                    }
                    self.toBeDeleted = nil
                }, secondaryButton: .cancel() {
                    self.toBeDeleted = nil
                }
            )
        }
    }
    .onDelete(perform: deleteRow)
}

func deleteRow(at indexSet: IndexSet) {
    self.toBeDeleted = indexSet           // store rows for delete
    self.showingDeleteAlert = true
}

backup 备份

In iOS 15+ you can use swipe actions and confirmationDialog在 iOS 15+ 中,您可以使用滑动操作和confirmationDialog对话框

@State private var showingDeleteAlert = false

List {
    ForEach(data, id: \.self) { item in
        Text(item)
        .swipeActions {
            Button("Delete", role: .destructive) {
                showingDeleteAlert = true
            }
        }
        .confirmationDialog(
            Text("..."),
            isPresented: $showingDeleteAlert,
            titleVisibility: .visible
        ) {
             Button("Delete", role: .destructive) {
             withAnimation {
                deleteItem(item)
             }
        }
    }
}

func deleteItem(_ item: NSManagedObject) {
        viewContext.delete(item)
        do {
            try viewContext.save()
        } catch let error {
            print("Error: \(error)")
        }
    }
}

Continuing the answer by @vadian and the comments to his answer, this code works for me with minimal glitching.继续@vadian 的回答和对他的回答的评论,这段代码对我有用,故障最少。 Basically, move the confirmation dialog to a lower level, but in order to keep the reference to the item being deleted, add a @State var to track it.基本上,将确认对话框移到较低级别,但为了保留对被删除项目的引用,添加一个 @State var 来跟踪它。

Note: The reason I say "minimal glitching", is that when you complete the swipe to delete, the row does actually disappear and instantly reappears in the same spot.注意:我说“最小故障”的原因是,当您完成滑动以删除时,该行实际上消失并立即重新出现在同一位置。 It's almost imperceptible without using slow animations in the simulator.如果不在模拟器中使用慢速动画,这几乎是不可察觉的。 But it's the least glitchy solution I've found so far.但这是迄今为止我发现的故障最少的解决方案。 If anyone can figure out a way to have it perfect, I'm all ears.如果有人能想出一种让它变得完美的方法,我会洗耳恭听。

@State private var showingDeleteAlert = false
@State private var itemToDelete: Item? = nil

List {
    ForEach(data, id: \.self) { item in
        Text(item)
        .swipeActions {
            Button("Delete", role: .destructive) {
                self.itemToDelete = item
                showingDeleteAlert = true
            }
        }
    }
    .confirmationDialog(
        Text("..."),
        isPresented: $showingDeleteAlert,
        titleVisibility: .visible
    ) {
         Button("Delete", role: .destructive) {
         withAnimation {
            deleteItem(itemToDelete)
         }
    }
}

func deleteItem(_ item: NSManagedObject?) {
        guard let item else { return }

        viewContext.delete(item)
        do {
            try viewContext.save()
        } catch let error {
            print("Error: \(error)")
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM