MenuBarExtraAccess

Platforms - macOS 13.0 Xcode 14 License: MIT

为您提供对 SwiftUI MenuBarExtra额外访问权限。

为什么?

没有第一方 MenuBarExtra API 来获取或设置菜单的显示状态、访问状态栏项目或访问弹出窗口的 NSWindow。(截至 Xcode 16.1 仍然如此)

库特性

入门指南

该库以 Swift Package Manager (SPM) 包的形式提供。

在将库添加到项目或 Swift 包时,请使用 URL https://github.com/orchetect/MenuBarExtraAccess

然后导入库

import SwiftUI
import MenuBarExtraAccess

标准菜单样式

通过单击窗口中的按钮显示菜单额外菜单的示例

@main struct MyApp: App {
    @State var isMenuPresented: Bool = false
    
    var body: some Scene {
        WindowGroup {
            Button("Show Menu") { isMenuPresented = true }
        }
        
        MenuBarExtra("MyApp Menu", systemImage: "folder") {
            Button("Menu Item 1") { print("Menu Item 1") }
            Button("Menu Item 2") { print("Menu Item 2") }
        }
        .menuBarExtraStyle(.menu)
        .menuBarExtraAccess(isPresented: $isMenuPresented) { statusItem in // <-- the magic ✨
             // access status item or store it in a @State var
        }
    }
}

窗口样式

弹出窗口中的按钮关闭弹出窗口并执行操作的示例

@main struct MyApp: App {
    @State var isMenuPresented: Bool = false
    
    var body: some Scene {
        MenuBarExtra("MyApp Menu", systemImage: "folder") {
            MyMenu(isMenuPresented: $isMenuPresented)
            	.introspectMenuBarExtraWindow { window in // <-- the magic ✨
                    window.animationBehavior = .alertPanel
                }
        }
        .menuBarExtraStyle(.window)
        .menuBarExtraAccess(isPresented: $isMenuPresented) { statusItem in // <-- the magic ✨
             // access status item or store it in a @State var
        }
    }
}

struct MyMenu: View {
    @Binding var isMenuPresented: Bool

    var body: some View {
        Button("Perform Action") { 
            isMenuPresented = false 
            performSomeAction()
        }
    }
}

多个 MenuBarExtra

MenuBarExtraAccess 完全兼容应用程序中的一个或多个 MenuBarExtra。

只需向 .menuBarExtraAccess().introspectMenuBarExtraWindow() 添加一个索引号参数,该参数反映 MenuBarExtra 声明的顺序。

var body: some Scene {
    MenuBarExtra("MyApp Menu A", systemImage: "folder") {
        MyMenu(isMenuPresented: $isMenuPresented)
            .introspectMenuBarExtraWindow(index: 0) { window in // <-- add index 0
                // ...
            }
    }
    .menuBarExtraStyle(.window)
    .menuBarExtraAccess(index: 0, isPresented: $isMenuPresented) // <-- add index 0
    
    MenuBarExtra("MyApp Menu B", systemImage: "folder") {
        MyMenu(isMenuPresented: $isMenuPresented)
            .introspectMenuBarExtraWindow(index: 1) { window in // <-- add index 1
                // ...
            }
    }
    .menuBarExtraStyle(.window)
    .menuBarExtraAccess(index: 1, isPresented: $isMenuPresented) // <-- add index 1
}

未来展望

希望 Apple 在未来版本的 SwiftUI 中实现这些功能(以及更多)的原生版本!

在此之前,已提交雷达作为功能请求:FB11984872

菜单构建器

查看 MacControlCenterUI,这是一个基于 MenuBarExtraAccess 构建的 SwiftUI 包,用于轻松构建控制中心风格的菜单。

已知问题

作者

由一群穿着风衣并自称 @orchetect 的 🐹 仓鼠编写。

许可证

在 MIT 许可证下获得许可。 有关详细信息,请参阅 LICENSE

赞助

如果您喜欢使用 MenuBarExtraAccess 并希望在经济上为开源做出贡献,GitHub 赞助将不胜感激。 也欢迎反馈和代码贡献。

贡献

欢迎贡献。 鼓励在新提交功能或修改的 PR 之前,先在 Discussions 中发帖。