macOS 开发之菜单栏形式的状态栏小工具
不知道大家有没有用过菜单栏形式的状态栏工具,类似于之前写的 NSPopover 的工具在系统顶栏占用一个图标,不同的是点击之后弹出的不是弹窗而是一个菜单,就像下面截图展示的工具,本文就讲一下如何实现。
平台
- macOS 10.15
- Xcode 11.1
- Swift 5.1
本文使用上述平台实现验证,版本不同可能有些差异,但基本思路一致。
工程新建及配置
-
打开xcode新建工程, macOS -> App -> Next:
-
输入工程名称:
MenuToolDemo
,language 选择Swift
,User Interface 选择 SwiftUI(本文不会用到 SwiftUI)点击 Next: -
选择合适的目录,点击 create 即可打开创建的新工程;
-
点击运行按钮,可以看到程序运行,出现一个显示 hello world 的窗口,同时dock上出现了应用图标,这不是我们想要的,设置一下不显示它们:
-
工程导航栏选中工程
MenuToolDemo
,打开Info
标签页; -
可以看到
Custom macOS application Target Properties
组,添加新的配置Application is agent(UI Element)
,布尔属性,值为 YES:
-
-
重新运行程序,可以看到已经不显示Dock图标;
-
删除 ContentView.swift 文件;
-
打开文件
AppDelegate.swift
,删掉两个地方代码:var window: NSWindow!
// Create the SwiftUI view that provides the window contents. let contentView = ContentView() // Create the window and set the content view. window = NSWindow( contentRect: NSRect(x: 0, y: 0, width: 480, height: 300), styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView], backing: .buffered, defer: false) window.center() window.setFrameAutosaveName("Main Window") window.contentView = NSHostingView(rootView: contentView) window.makeKeyAndOrderFront(nil)
-
再次运行程序,主窗口也不显示了,连菜单栏也木有了,不要着急,咱继续。
添加状态栏按钮
打开文件AppDelegate.swift
,在类中添加属性,这一步是创建一个状态栏按钮,设置宽度属性NSStatusItem.squareLength
,代码如下:
let statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.squareLength)
状态栏按钮总该需要一个图标吧!打开Assets.xcassets
,右击显示AppIcon
下方的空白区,选择New Image Set
,重命名为statusIcon
,当然这个名字随便定,选中这个图集,会看到右侧有配置区,配置图集按照Template Image
渲染。
看到有三个虚线框空白区,这就是图片区,状态栏按钮的图片基本大小为 $18px\times18px$ ,还需2倍和3倍的适用于视网膜屏幕的mac,像素分别是 $36px\times36px$ 和 $54px\times54px$ ,可以使用以下我提供的图标:
分别将图拖到对应位置:
找到applicationDidFinishLaunching
在其中添加以下代码,为状态栏按钮配置图标和行为:
if let button = statusItem.button {
button.image = NSImage(named: "StatusIcon")
}
此时运行程序会看到状态栏中出现了我们定义的按钮,当然此时鼠标单击没有任何动作发生。
前面设置图片集渲染方式为
Template Image
,是为了适配不同的状态栏主题,因为macOS还有个暗黑主题不是?
两种主题下的效果如下:
添加菜单
打开 Main.storyboard 文件,使用以下两种方式中的任意一种,打开控件库窗口:
-
按下快捷键
Command
+Shift
+L
-
点击 Xcode 窗口右上角的 ➕ 按钮
在搜索框中输入 Menu
,就会检索到 NSMenu 控件:
鼠标左键在控件单击不松拖放到文件 Main.storyboard
的左边栏 First Responder 下面:
按下快捷键 Ctrl
+ Option
+ Command
+ Enter
(⌃⌥⌘⏎) 打开 Assitant 编辑器:
按住 Ctrl
键,鼠标左键按住 Menu 控件不松拖动至辅助编辑器的文件 AppDelegate.swift 中,在弹出的属性添加弹窗中输入属性名 menu
,点击 Connect 就会看到 AppDelegate.swift 中出现 menu 属性: