我见过一个使用 Menu 的应用程序,当您按下 a 按钮时,系统会要求我“确认”。这促使我重构我的应用程序:
@State var confirmDeletion: Bool = false
VStack {
Button(role: .destructive) {
self.confirmDeletion = true
} label: {
Spacer()
Text("Delete")
Spacer()
}.confirmationDialog(
"Are you sure?",
isPresented: $confirmDeletion,
titleVisibility: .visible
) {
Button("Yes", role: .destructive) {
DispatchQueue.main.async {
Task {
await doSomeAsynWork()
}
}
}
Button("Cancel", role: .cancel) {}
}
}
这效果很好。现在使用菜单进行重构:
Menu {
[..] // other buttons
Button(role: .destructive) {
print("I was called... and that's it")
self.confirmDeletion = true
} label: {
Label("Delete", systemImage: "trash")
}.confirmationDialog(
"Are you sure?",
isPresented: $confirmDeletion,
titleVisibility: .visible
) {
Button("Yes", role: .destructive) {
DispatchQueue.main.async {
Task {
await doSomeAsynWork()
}
}
}
Button("Cancel", role: .cancel) {}
}
} label: {
Label("Menu", systemImage: "line.horizontal.3.decrease.circle")
}
我知道,当您按任何菜单按钮时,它会立即关闭,所以这就是
confirmationDialog
不起作用的原因。我可以用菜单实现 confirmationDialog
吗?
将其移到
Menu
之外,例如
Menu {
[..] // other buttons
Button(role: .destructive) {
print("I was called... and that's it")
self.confirmDeletion = true
} label: {
Label("Delete", systemImage: "trash")
}
} label: {
Label("Menu", systemImage: "line.horizontal.3.decrease.circle")
}
.confirmationDialog( // << here !!
"Are you sure?",
isPresented: $confirmDeletion,
titleVisibility: .visible
) {
Button("Yes", role: .destructive) {
DispatchQueue.main.async {
Task {
await doSomeAsynWork()
}
}
}
Button("Cancel", role: .cancel) {}
}
Asperi 的方法是正确的,但另一种方法是使用嵌套菜单进行确认,如下所示:
Menu {
// [..] other buttons
Menu {
Button(role: .destructive) {
// execute deleting
} label: {
Label("Confirm", systemImage: "trash")
}
Button {
// do nothing
} label: {
Label("Cancel", systemImage: "xmark")
}
} label: {
Label("Delete", systemImage: "trash")
}
} label: {
Label("Menu", systemImage: "line.horizontal.3.decrease.circle")
}
这样做的一个问题是,“删除”并未显示为具有破坏性,只有“确认删除”才是。不过,它确实显示了内联确认,这很有用。