
macOS 开发 - 创建 SwiftUI + AppKit 状态栏应用(popover视图)
🎯简单几步打造 macOS 原生状态栏应用!从零开始构建一个专业的状态栏 Popover 工具,使用 SwiftUI 构建界面 + AppKit 实现系统集成。包含完整可运行代码、全屏模式兼容方案、键盘快捷键支持。适合想要创建菜单栏工具的 macOS 开发者 🚀
本文将带你从零开始,逐步创建一个完整的 macOS 状态栏 popover 应用。我们将使用 SwiftUI + AppKit 混合开发模式,每一步都提供可运行的代码,让你能够跟着操作并实时验证效果。
为什么选择 SwiftUI + AppKit 混合开发
SwiftUI 的优势:
- 声明式 UI 开发,代码简洁高效
- 强大的状态管理和响应式编程
- 优秀的动画和视觉效果支持
AppKit 的必要性:
- 完整的状态栏 API 支持
- 精确的窗口层级和空间控制
- 系统级事件监听和处理
混合开发的价值:
- 充分发挥两个框架的优势
- 渐进式迁移,降低开发风险
- 更好的系统集成能力
注意: 如果只需要简单的菜单功能,macOS 13+ 的 MenuBarExtra 可能更适合。但对于需要复杂交互的 popover 界面,SwiftUI + AppKit 是更稳定的选择。第一步:创建 Xcode 项目
1. 新建项目
- 打开 Xcode,选择 "File" > "New" > "Project"
- 选择 "macOS" > "App"
- 填写项目信息:
- Product Name:
StatusBarDemo - Interface:
SwiftUI - Language:
Swift - Use Core Data: 不选择
- Product Name:
- 选择保存位置并创建项目
2. 项目初始设置
创建项目后,你会看到默认的 StatusBarDemoApp.swift 文件。我们需要对其进行修改。
首先,将默认的 StatusBarDemoApp.swift 内容替换为:
此时运行项目(⌘+R),你应该能看到一个标准的 macOS 窗口。
第二步:配置应用为状态栏模式
修改 StatusBarDemoApp.swift
我们需要将应用配置为状态栏模式。将 StatusBarDemoApp.swift 的内容替换为:
运行并验证
按 ⌘+R 运行应用:
- 你不应该看到任何窗口
- Dock 中不应该有应用图标
- 在 Xcode 的控制台中应该能看到 "✅ 状态栏应用启动成功"
如果一切正常,说明应用已经成功配置为状态栏模式。
第三步:创建状态栏图标
1. 创建状态栏控制器文件
在 Xcode 中:
- 右键点击项目文件夹
- 选择 New File...
- 选择 macOS > Swift File
- 命名为
StatusBarController.swift - 点击 Create
2. 实现基础状态栏控制器
在 StatusBarController.swift 中添加以下代码:
3. 在应用启动时初始化状态栏
修改 StatusBarDemoApp.swift 中的 AppDelegate:
4. 运行并验证
按 ⌘+R 运行应用:
- 你应该在状态栏右侧看到一个星形图标 ⭐
- 点击图标,控制台应该显示 "🖱️ 状态栏图标被点击了!"
如果看到了状态栏图标并且点击有响应,说明基础功能已经实现!
第四步:创建 SwiftUI Popover 视图
1. 创建 Popover 内容视图
创建新文件 StatusBarPopView.swift:
2. 修改状态栏控制器以支持 Popover
更新 StatusBarController.swift
3. 运行并测试
按 ⌘+R 运行应用:
- 点击状态栏的星形图标
- 应该会显示一个美观的 popover 窗口
- 尝试点击 +/- 按钮测试计数器功能
- 点击 popover 外部,窗口应该自动关闭
如果 popover 正常显示和交互,恭喜你已经完成了基础功能!
第五步:解决全屏模式显示问题
在某些情况下(特别是全屏应用场景),popover 可能无法正确显示。我们需要添加窗口层级配置。
更新 showPopover 方法
在 StatusBarController.swift 的 showPopover 方法后添加窗口配置方法:
第六步:添加键盘支持和事件监听
为了提升用户体验,我们添加 ESC 键关闭和点击外部关闭的功能。
完善状态栏控制器
在 StatusBarController 类中添加事件监听器存储和相关方法:
第七步:测试和验证
最终测试清单
运行应用并进行以下测试:
- 基础功能测试:
- ✅ 状态栏图标正确显示
- ✅ 点击图标显示 popover
- ✅ popover 内容正确渲染
- ✅ 计数器功能正常工作
- 交互测试:
- ✅ 点击 popover 外部自动关闭
- ✅ 按 ESC 键关闭 popover
- ✅ 重复打开/关闭 popover 正常
- 全屏模式测试:
- ✅ 打开任意全屏应用(如全屏的浏览器)
- ✅ 点击状态栏图标,popover 能正常显示
- ✅ 在不同的桌面空间中测试
完整代码结构
此时你的项目应该包含以下文件:
常见问题与解决方案
Q: Popover 在某些情况下无法显示?
A: 检查窗口层级设置,确保 window.level 至少为 .statusBar。在全屏应用中可能需要设置为 .floating。
Q: 如何让状态栏图标支持拖拽?
A: 实现 NSStatusBarButton 的拖拽相关代理方法,或使用自定义的 NSView。
Q: 如何持久化用户设置?
A: 使用 @AppStorage 或 UserDefaults:
Q: 如何在多显示器环境下正确显示?
A: 使用 collectionBehavior 的 .moveToActiveSpace 选项,确保 popover 跟随当前活跃的显示器。
Q: 应用启动时显示在 Dock 中?
A: 确保在 applicationDidFinishLaunching 中正确设置:
Q: 如何自定义状态栏图标?
A: 将自定义图标添加到项目中,然后:
总结
通过 SwiftUI + AppKit 混合开发模式,我们可以创建功能强大且用户体验出色的 macOS 状态栏应用。关键要点包括:
- 正确的窗口配置:确保 popover 在所有情况下都能正常显示
- 完善的事件处理:提供符合用户预期的交互体验
- 良好的内存管理:避免内存泄漏和性能问题
- 版本兼容性:适配不同 macOS 版本的特性差异
这种开发模式既能享受 SwiftUI 的开发效率,又能充分利用 AppKit 的系统集成能力,是现代 macOS 应用开发的理想选择。



