SwiftUI 菜单上是否可以有一个确认对话框?

问题描述 投票:0回答:2

我见过一个使用 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
吗?

xcode swiftui xcode13
2个回答
4
投票

将其移到

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) {}
    }

0
投票

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")
}

这样做的一个问题是,“删除”并未显示为具有破坏性,只有“确认删除”才是。不过,它确实显示了内联确认,这很有用。

© www.soinside.com 2019 - 2024. All rights reserved.