【问题标题】:How to Make macOS App Window Hidden When Closed and Reopened With Menu Bar Item?如何在关闭并使用菜单栏项重新打开时隐藏 macOS 应用程序窗口?
【发布时间】:2021-06-08 12:52:56
【问题描述】:

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

这意味着:

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

我的故事板如下所示:

我尝试了以下方法:

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

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

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

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

【问题讨论】:

  • @Willeke 你没有看问题的最后一部分
  • 我确实阅读了您的问题。是什么让你认为我没有?
  • @Willeke 这个问题是关于从菜单栏中的NSStatusItem 停用和激活应用程序,包括隐藏/取消隐藏停靠图标,而您建议的副本是关于标准的关闭和打开窗口场景。
  • 问题是“如何使 macOS 应用程序窗口在关闭并使用菜单栏重新打开时隐藏?”。这是关于一个窗口。

标签: swift xcode macos cocoa


【解决方案1】:

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

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

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

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

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()
        }
    }
}

【讨论】:

  • 是的,这几乎是我所需要的。但是,activateWindow 运行后,该窗口不再出现。应用程序图标确实出现在 Dock 中,菜单确实出现在状态栏中。
  • @Wendell 也许NSApp.windows.first 是空的?在这种情况下,您必须重新创建窗口,或者确保您没有从内存中删除初始窗口。
  • 我用if let window = NSApp.windows.first {检查NSApp.windows.first,结果不是nil...
  • @Wendell 试试window.makeKeyAndOrderFront(nil)
  • 如果你说的是NSApp.windows.first?.makeKeyAndOrderFront(nil),还是一样的问题。
猜你喜欢
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-07
  • 2017-07-13
相关资源
最近更新 更多