如何在 SwiftUI 中以降低的透明度获取菜单项的 AccentColor 背景?

Dam*_*aux 6 macos swift swiftui

使用 AppKit,您可以将NSMenuItems 添加到NSMenu. 我看到SwiftUI中有一个类似NSMenu的东西,即MenuButton. 但我找不到任何有关其工作原理的文档。

我尝试了以下方法:

MenuButton("+") {
    Button("New contact") { print("Create new contact") }
    Button("New group") { print("Create new group") }
}
Run Code Online (Sandbox Code Playgroud)

这给了我这个

打开的菜单按钮

它看起来几乎没问题,但是当我在系统首选项中启用“降低透明度”时

  • 这些按钮的背景颜色与菜单不同(请注意菜单项上方和下方的颜色稍浅)。
  • 当我将鼠标悬停在菜单项上时,它们的背景颜色不会像普通 macOS 菜单那样发生变化。见下图:

突出显示的菜单项

我还尝试使用修改器手动更改背景颜色.background(),但这不会影响菜单项的整个宽度。

MenuButton("+") {
    Button("New contact") { print("Create new contact") }
        .background(Color.accentColor)
    Button("New group") { print("Create new group") }
}
Run Code Online (Sandbox Code Playgroud)

手动更改背景的菜单

我想这是因为我将Buttons 放在里面,MenuButton而它可能需要一些其他 SwiftUI 元素。我应该在 MenuButtons 中放置哪些元素来创建一个看起来正常的 macOS 菜单,如下所示?

在 Catalina 上正确呈现 MenuButton

[更新]macOS Big Sur

我也在大苏尔尝试过这个。虽然背景渲染正确,但在大苏尔,文本颜色现在很混乱。

Big Sur 上的菜单突出显示不正确

小智 1

ButtonStyle我想我通过配置 a并将其应用于通用结构找到了部分解决方案MenuButton。但请注意, 的条件更改.foregroundColor不会由个人的Button()继承Text()。而且颜色也不对。

也许有人想对此进行改进。

struct DetectHover: ButtonStyle {
    @State private var hovering: Bool = false

    public func makeBody(configuration: DetectHover.Configuration) -> some View {
        configuration.label
            .foregroundColor(self.hovering ? Color.white : Color.primary)
            .background(self.hovering ? Color.blue : Color.clear)
            .onHover { hover in
                self.hovering = hover
            }
    }
}
Run Code Online (Sandbox Code Playgroud)
MenuButton(label: Image(nsImage: NSImage(named: NSImage.actionTemplateName)!)) {

// Buttons

}.buttonStyle(DetectHover())
Run Code Online (Sandbox Code Playgroud)

结果