如何在 SwiftUI 中配置用于删除和禁用的 ContextMenu 按钮?

How to configure ContextMenu buttons for delete and disabled in SwiftUI?

我尝试配置 contextMenu 中的按钮,但它不起作用。

Text("A label that have context menu")
    .contextMenu {
        Button(action: {
            // remove it
        }) {
            Text("Remove")
                .foregroundColor(.red) // Not working
            Image(systemName: "trash")
        }.disabled(true) // Not working
    }

我有:

我要查找的内容:(删除调用 按钮)

我会在 UIKit 中创建一个像下面这样的 UIAction,但我找不到任何修饰符或无论如何都无法将它带到 SwiftUI

let delete = UIAction(title: "Remove", image: UIImage(systemName: "trash"), attributes: .destructive) { action in
    // remove it
}

切换确定视图是否可见的布尔值有效:

struct ContentView: View {
    @State var textVisible = true
    var body: some View {
        Group {
            if textVisible {
                Text("Hello World")
                .contextMenu {
                    Button(action: {
                        self.textVisible = false
                    }) {
                        HStack {
                            Text("Remove")
                            Image(systemName: "trash")
                        }
                    }
                }
            }
        }
    }
}

当然,由于上下文菜单附加到已删除的 Text,它将被永久删除,除非您有其他东西(例如 Button)切换布尔值(textVisible 在这种情况下)。

Edit:OP 想知道如何在上下文菜单中制作按钮 disabled/destructive(grey/red 前景色),但我相信从2019 年 10 月 20 日,SwiftUI 有一个错误,不允许上下文菜单中的任何按钮是红色以外的任何颜色。否则,将按钮设置为 .disabled(true) 应该给它一个灰色并禁用它,将按钮的前景色设置为红色 (foregroundColor(.red)) 应该使按钮具有破坏性。

Apple 提倡使用 Menu 而不是 ContextMenu。如果您想禁用菜单中的选项,您可以使用以下代码。您可以在修饰符中使用表达式使其动态化

关于样式 - 目前无法为菜单中的单个项目设置样式。即使,如果您应用样式,它也不会起作用。

struct ContentView: View {
    var body: some View {
        
        VStack {
            Menu("Actions") {
                Button("Duplicate", action: {})
                Button("Rename", action: {})
                Button(action: {}) {
                    
                    Label("Delete", systemImage: "trash")
                    
                }.disabled(true)
                Button(action: {}) {
                   
                    Label("Call", systemImage: "phone")
                    
                }.disabled(true)
            }      
        }
    }
}

iOS 15

从 iOS 15 开始,我们可以向 Button 添加一个 role,这样它就可以自动调整其外观:

这是一个例子:

Text("A label that have context menu")
    .contextMenu {
        Button(role: .destructive) {
            print("removing...")
        } label: {
            Text("Remove")
            Image(systemName: "trash")
        }
    }

iOS 15

现在支持所有询问的情况

破坏性:(作品来自 iOS 15)

.destructive 设置为按钮的 role 参数:

Button(role: .destructive) { //  This argument
    // delete something
} label: {
    Label("Delete", systemImage: "trash")
}


已禁用:(适用于 iOS 14.2)

向按钮添加 .disabled 修饰符。

Button {
    // call someone
} label: {
    Label("Call", systemImage: "phone")
}.disabled(true) //  This modifier


分频器:(来自 iOS 14 的作品)

直接使用 Divider() 视图。


完整演示:

⚠️切记! 不要 使用 image 而不是 systemImage 在按钮上显示 SFSymbol!