在NSWindow关闭后,activateIgnoringOtherApps和makeKeyAndOrderFront无法正常工作

时间:2016-05-30 08:59:06

标签: macos cocoa nswindow nsstoryboard

我开始讲故事板项目。我把Menubar项目。 单击菜单栏项目时,将在AppDelegate.swift中触发以下方法。

func setWindowVisible() {
    NSApp.activateIgnoringOtherApps(ture)
    NSApp.mainWindow?.makeKeyAndOrderFront(self)
}

这将我的应用程序放在了前面。但是一旦我点击关闭按钮,窗口上的红色按钮,它就永远不会起作用。

无论我关闭窗口,它都曾用于非基于故事板的项目。

我已经设置了

NSApp.mainWindow?.releasedWhenClosed = false

在applicationDidFinishLaunching()

有人可以帮我吗?

2 个答案:

答案 0 :(得分:4)

releasedWhenClosed中设置applicationDidFinishLaunching无效,因为此时mainWindow属性为零。 →执行此方法后将创建窗口。

在Interface Builder中创建窗口时,releasedWhenClosed默认为false。

关闭窗口后,mainWindow属性可能为nil,因为那时不再有mainWindow了。来自文档:

  

当app的storyboard或nib文件尚未完成加载时,此属性中的值为nil。当应用程序处于非活动状态或隐藏状态时,它也可能是零。

通过从windows NSApp数组中访问窗口,我能够再次显示窗口(关闭后)。

NSApp.activateIgnoringOtherApps(true)
NSApp.windows[0].makeKeyAndOrderFront(self)

如果您有多个窗口,则需要在数组中找到正确的窗口。

答案 1 :(得分:0)

想将Kyle KIM的答案纳入自己的答案,因为上述具有数组访问权限的解决方案对我来说是一个例外。

在我的用例中,我使用this keyboard shortcuts library将应用程序置于前台。

我还将它与新的 SwiftUI应用功能一起使用,而且值得庆幸的是,它们都可以一起使用-即使您单击关闭按钮,它也会再次调用。

df = df.set_index("date", drop=False)
df = df.sort_index()

date = pd.to_numeric(df["date"].copy())  # it wasn't letting me aggregate dates so we have to convert to float then back to dates
date[df.value.isna()] = None
latest_index = date.groupby(df.group).rolling("35D").max()
latest_index = pd.to_datetime(latest_index)

!NSApp.isActive和密钥窗口检查都是必需的,因为当用户单击“关闭按钮”时,该寡妇不再是密钥,而是仍然处于活动状态。该应用程序保持活动状态,直到他们单击其他应用程序为止。您可以通过窗口的焦点颜色看到这种情况。

请注意,此AppDelegate并不是我应用程序的主要入口点,它与swiftUI一起使用:

class AppDelegate: NSObject, NSApplicationDelegate {

var window: NSWindow?

func applicationDidBecomeActive(_ notification: Notification) {
    self.window = NSApp.mainWindow
}

func applicationDidFinishLaunching(_ aNotification: Notification) {
    KeyboardShortcuts.onKeyUp(for: .toggleApp) {
        if !NSApp.isActive || !(self.window?.isKeyWindow ?? false) {
            NSApp.activate(ignoringOtherApps: true)
            self.window?.makeKeyAndOrderFront(self)
        } else {
            print("App already active")
        }
    }
}
}