通过 SwiftUI 的 MenuBarEtra 实现菜单栏小工具
macOS 开发

通过 SwiftUI 的 MenuBarEtra 实现菜单栏小工具

在 macOS 下有许多优秀的状态栏小工具,如果你想开发自己的状态栏小工具,看我这篇文章应该会对你有所帮助!很早之前写过一篇使用 AppKit 实现的文章,而今天,我们完全通过 SwiftUI 的 MenuBarExtra 快速实现,适用于 macOS 13+ 版本!

1,522次点击5分钟阅读

若使用 Appkit 的实现方式请参考:macOS 开发之菜单栏形式的状态栏小工具

实现纯状态栏小工具,包含以下操作:

  1. 添加 MenuBarExtra 实现状态栏小工具;
  2. 删除主窗口;
  3. 实现 Dock 栏上不显示应用图标。
如果只是在已开发应用增加状态栏的操作入口,可忽略第二、三步!

平台

  • macOS 13.5.2
  • Xcode 15.0
  • swift 5.9
本文使用上述平台实现,版本不同可能有些差异,但基本思路一致。

新建工程

我们先新建一个工程,当然也可以在自己已有工程中添加实现,注意要将应用的 Deplyment Target 设置到 13.0 以上。

New Project -> macOS -> App,点击 Next,我这里 Product Name 设置为 MenuBarAppDemoLanguage 选择 SwiftInterface 选择 SwiftUI,最后选择保存目录点击创建 Create

新建项目 - MenuBarAppDemo

记得要配置一下 ProjectTargetDeployment Target 版本。

配置项目的部署版本
配置项目 Target 的部署版本

MenuBarExtra 支持 macOS 13.0+,我这里就选 13.0 了。

MenuBarExtra 官方说明

添加 MenuBarExtra

打开 App 文件 MenuBarAppDemoApp.swift,在 WindowsGroup 下面添加合适的 MenuBarExtra 即可。

添加 MenuBarExtra

有八种方式,按照自己的需求选择就好,我这里选择使用 SF Symbol 图像作为图标的接口 MenuBarExtra(content:label:)

  • 点击图标显示的内容为 ContentView.swift 中定义的内容;
  • 自定义状态栏显示的内容,这里添加了 ImageText
  • menuBarExtraStyle 选择了 window
    • .menu: 将内容渲染为从菜单栏图标下拉的菜单,如下形式:
menu 风格的菜单栏小工具弹窗
  • .window: 将内容渲染在一个类似于弹出窗口的窗口中,如下形式:
windows 风格的菜单栏小工具弹窗

+r运行应用程序,可以看到状态栏出现了泰迪熊的图标和 Teddy ,点击也能看到显示 ContentView 的内容,我们就可以通过修改 ContentView.swift 自定义内容了,比如:

  • 修改为 Text("hello, Teddy!")
  • 添加一个退出应用的按钮,并绑定了 +q的快捷键。

🎉再次+r运行,菜单栏是这样的:

Demo 的 windows 风格弹窗

🤔如果修改 menuBarExtraStyle.menu,则会按照菜单形式渲染内容:

Demo 的 menu 风格弹窗
🖌️ .menuBarExtraStyle.menu 时某些控件可能会失效😂,只能显示内容(按照菜单项高度、图像以 template 方式渲染)无法交互🤯,比如 Stepper、Slider 等,像基本的 Button、Text、Divider、Image 等还是能正常显示的。
💡如果你想完全不受限制的定制自己希望显示的内容还是选 .window 吧!

实现Dock 栏不显示应用图标

导航栏选择 MenuBarAppDemoTargets 选择 MenuBarAppDemo,找到 Info 下的 Custom macOS Application Target Properties,添加一项 Application is agent (UIElement) 并设置值为 YES

设置 Application is agent (UIElement)

+r 运行应用程序,正常的话在 Dock 栏就看不到应用程序的图标了。

删除主窗口

直接删除 MenuBarAppDemoApp.swift 中的 windowGroup 内容就好了,最终代码如下:

+r 运行应用程序,正常的话应用的主窗口也没有了。

🎉 至此,纯菜单栏小工具的架子也就搭好了,后面根据自己的需要调整 ContentView 内容就好啦,是不是很简单🚀!

附件

本文 Demo 代码: MenuBarAppDemo

总结

本文的方式是纯 SwiftUI 的实现方式,受到系统版本的限制,大家根据自己的 App 的情况酌情选择方案!除了macOS 开发之菜单栏形式的状态栏小工具讲中使用 Appkit 方式之外,也有 SwiftUI + Appkit 的方式(如下代码),不管用什么方式自己用着顺手、满足功能和开发需求就好,不必过于纠结!我个人更倾向于纯 SwiftUI 的方式(因为这是 Apple 发力的方向,路久但可期🔥),相信你也会有自己明确的选择!

相关文章