如何使 macOS 应用程序 Window 在关闭并使用菜单栏项重新打开时隐藏?

How to Make macOS App Window Hidden When Closed and Reopened With Menu Bar Item?

我正在开发一个 macOS 应用程序(使用 Swift 和 Storyboard),它 window 的行为类似于 Adob​​e Creative Cloud 应用程序。经过数小时的研究,我找不到最佳解决方案。

这意味着:

  1. 当应用程序启动时,主 window 会在状态栏上显示各种菜单,一个图标出现在 Dock 中,一个图标出现在状态栏中。
  2. 当用户单击红色 X 时,主 window 和停靠栏中的图标被隐藏。
  3. 可以通过单击状态栏图标重新打开主应用 window。停靠栏图标重新出现。

我的故事板是这样的:

我试过以下方法:

  1. 通过将 Application is agent (UIElement) 设置为 YES,我能够关闭主应用程序 window,同时保持应用程序处于活动状态。但是,应用程序图标没有显示在停靠栏中,状态栏左侧也没有菜单。

  2. 我可以通过单击状态栏图标来启动新应用程序 window。但是这样做只会打开一个全新的 window,而不管 window 是否已经出现(我只希望一个 window 出现)。

let storyboard = NSStoryboard(name: "Main", bundle: nil)
guard let window = storyboard.instantiateController(withIdentifier: .init(stringLiteral: "main")) as? WindowController else { return }
window.showWindow(self)

非常感谢任何能提供帮助的人!

不要使用 Application is agent 方法,而是更改 NSAppactivationPolicy

要在关闭(最后一个)window 后动态隐藏图标,请在您的 AppDelegate 中使用:

func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
    NSApp.setActivationPolicy(.accessory)
    return false
}

并使用与此类似的东西来初始化您的菜单栏图标并激活 window 包括停靠栏图标:

class ViewController: NSViewController {

    var status: NSStatusItem?

    override func viewDidLoad() {
        super.viewDidLoad()

        status = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
        status?.button?.title = "Test"
        status?.button?.action = #selector(activateWindow(_:))
        status?.button?.target = self
    }

    @IBAction func activateWindow(_ sender: AnyObject) {
        NSApp.setActivationPolicy(.regular)
        DispatchQueue.main.async {
            NSApp.windows.first?.orderFrontRegardless()
        }
    }
}