macOS 应用程序坞和菜单栏设置

孙康

和 Windows 操作系统有所不同的是,macOS 中多数应用程序关闭窗口后并不会退出,程序坞(Dock)还会显示该应用的图标,图标下的黑点也表示该应用处于打开状态。造成这种差异的原因是 Windows 使用的是 Single Document Interface (SDI) 式 GUI ,应用、窗口和文档具有一对一的关系;而 macOS 使用的是 Multiple Document Interface (MDI) 式 GUI,应用、窗体、文档具有一对多的关系。macOS 作为更古老的操作系统,在早期计算机算力不强时使用 MDI 可减少应用启动关闭造成的资源消耗。更多细节可阅读 知乎问答 。本文展示的代码片段出自开源项目 NuwaStone ,如需了解更多细节可参考该项目。

窗体重新显示

使用 Xcode 默认创建的 app 便是 MDI,虽然窗体关闭后应用并未退出,但点击程序坞应用图标并不会重新显示窗体,如需实现该功能需重写AppDelegate类的相关函数,代码如下。入参中的flag表示当前窗体是否关闭,如果关闭需查找当前系统所持有的窗体,将其置于前台。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool {
if flag {
return true
}

if let window = getMainWindow(sender) {
window.makeKeyAndOrderFront(self)
}
return true
}

func getMainWindow(_ sender: NSApplication) -> NSWindow? {
for window: AnyObject in sender.windows {
if window.frameAutosaveName == "Your Window Name" {
return window as? NSWindow
}
}
return nil
}

程序坞图标隐藏

如果不想在程序坞显示应用图标,也是修改AppDelegate文件。NSApp.setActivationPolicyAPI 可以很方便的设置应用状态,状态分为regularaccessoryprohibited。简单来说分别表示正常显示图标和窗口、不在 Dock 栏显示图标、不显示图标和窗口。这里展示的代码图标和窗体状态同步,如果隐藏图标,窗体也一同关闭。

1
2
3
4
5
6
7
8
9
10
@objc func hideDockIcon() {
NSApp.setActivationPolicy(.accessory)
getMainWindow(NSApplication.shared)?.close()
}

@objc func showDockIcon() {
NSApp.setActivationPolicy(.regular)
NSApp.activate(ignoringOtherApps: true)
getMainWindow(NSApplication.shared)?.makeKeyAndOrderFront(self)
}

常驻菜单栏设置

有些应用在桌面右上角会提供常驻的菜单,例如系统输入法、控制中心等。如果需要设置该功能,也是修改AppDelegate文件。这里为右上角的菜单栏添加了后台运行、显示窗体、关闭应用三个功能。button.toolTip是指鼠标停靠在菜单栏图标上时显示的提示信息,如果不设置则没有提示。

1
2
3
4
5
6
7
8
9
10
func setupMenuBar() {
let statusMenu = NSMenu()
statusMenu.addItem(withTitle: "Run in Background", action: #selector(hideDockIcon), keyEquivalent: "")
statusMenu.addItem(withTitle: "Show App Window", action: #selector(showDockIcon), keyEquivalent: "")
statusMenu.addItem(withTitle: "Quit", action: #selector(NSApplication.terminate(_:)), keyEquivalent: "q")

menuBar.button!.image = NSImage(named: NSImage.Name("Your Menu Icon Name"))
menuBar.button!.toolTip = "Your Tip Name"
menuBar.menu = statusMenu
}
  • Title: macOS 应用程序坞和菜单栏设置
  • Author: 孙康
  • Created at : 2023-07-09 12:13:25
  • Updated at : 2023-08-31 19:55:52
  • Link: https://conradsun.github.io/2023/07f5dbd820.html
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments
On this page
macOS 应用程序坞和菜单栏设置