[英]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
}
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.