使用确认对话框时,我在 swiftui 中删除列表单元格时遇到一些问题。
我希望按删除或滑动删除会弹出确认对话框。然而,它并不是每次都有效。有时确认会出现然后立即消失,有时它会按预期工作。我的代码中没有任何错误或警告,因此我不确定如何最好地解决此问题。如有任何帮助,我们将不胜感激。
这是视图结构体中的变量。我尝试整合我遇到问题的代码。
struct ProjectDetailView: View {
let project: Project
@Environment(\.modelContext) private var context
@Environment(\.dismiss) private var dismiss
@State private var showingDeleteMirrorAlert = false
@State private var mirrorToDelete: IndexSet?
var body: some View {
Form {
List {
DisclosureGroup("Mirrors") {
if project.mirrors.isEmpty {
ContentUnavailableView {
Image(systemName: "figure.strengthtraining.functional")
Text("This project has no mirrors.")
} description: {
Text("Add some if you want some.")
}
} else {
ForEach(project.mirrors) { mirror in
NavigationLink(destination: MirrorDetailView(mirrors: mirror)) {
MirrorCellView(mirror: mirror)
}
}
.onDelete { indexSet in
mirrorToDelete = indexSet
showingDeleteMirrorAlert = true
}
}
}
}
.confirmationDialog(
"Are you sure you want to delete this mirror?",
isPresented: $showingDeleteMirrorAlert,
titleVisibility: .visible
) {
Button("Delete", role: .destructive) {
if let indexSet = mirrorToDelete {
deleteMirror(indexSet: indexSet)
}
showingDeleteMirrorAlert = false
mirrorToDelete = nil
}
Button("Cancel", role: .cancel) {
showingDeleteMirrorAlert = false
mirrorToDelete = nil
}
} message: {
Text("This action cannot be undone.")
}
}
}
private func deleteMirror(indexSet: IndexSet) {
for index in indexSet {
let mirror = project.mirrors[index]
context.delete(mirror)
}
do {
try context.save()
} catch {
print("Error deleting mirror: \(error)")
}
}
}
这通常发生在存在某种与国家相关的冲突时。
在这种情况下,可能与确认对话框的 .destroy 角色有关,该角色从列表中删除该项目,如此处所述。
一种解决方法是将按钮的角色设置为 .none:
Button("Delete", role: .none) {
if let indexSet = mirrorToDelete {
deleteMirror(indexSet: indexSet)
}
showingDeleteMirrorAlert = false
mirrorToDelete = nil
}
这将导致按钮不再是红色,并且应用任何着色或其他样式似乎不起作用。如果您想保留红色按钮样式,可以尝试以下选项:
另一种解决方法是从使用 .onDelete 切换到 .swipeAction,如此处所述:
ForEach(project.mirrors) { mirror in
NavigationLink(destination: MirrorDetailView(mirrors: mirror)) {
MirrorCellView(mirror: mirror)
}
}
.swipeActions {
Button {
showingDeleteMirrorAlert = true
//deleteMirror(mirror.id)
} label: {
Label("Delete", systemImage: "trash")
}
.tint(.red)
}
通过使用 .swipeAction,您将无法再访问 .onDelete 的索引,但您将能够直接访问镜像对象本身,您可以将其传递给 deleteMirror。
您必须相应地修改您的deleteMirror函数,以接受mirror参数,而不是索引。