在 macOS 菜单栏中,应用程序的菜单项被禁用

5

我正在尝试在 macOS 上构建一个菜单栏应用程序。

我似乎无法弄清楚为什么某些菜单项是禁用的... 截图:

Screenshot of the app

正如您所看到的,退出菜单项已启用,当单击时退出应用程序。然而,首选项项目被禁用。

我的代码

AppDelegate.swift:

let menuBarItem = NSStatusBar.system().statusItem(withLength: NSSquareStatusItemLength)

func applicationDidFinishLaunching(_ aNotification: Notification) {
    menuBarItem.button?.image = NSImage(named: "MenuBarIcon")
    menuBarItem.menu = MenuBarMenu()
}

MenuBarMenu.swift:

class MenuBarMenu: NSMenu {
    init() {
        super.init(title: "Menu")
        self.addItem(withTitle: "Preferences...", action: #selector(MenuBarActions.openPreferencesWindow(_:)), keyEquivalent: "")
        self.addItem(NSMenuItem.separator())
        self.addItem(withTitle: "Quit", action: #selector(MenuBarActions.terminate(_:)), keyEquivalent: "")
    }

    required init(coder decoder: NSCoder) {
        fatalError("init(coder:) has not been impemented")
    }
}

class MenuBarActions {
    @objc static func terminate(_ sender: NSMenuItem) {
        NSApp.terminate(sender)
    }

    @objc static func openPreferencesWindow(_ sender: NSMenuItem) {
        print("preferences")
    }
}

我正在使用完全相同的方式创建MenuBarItems和选择器的相同结构,因此我对这种不一致感到有些困惑。为什么会发生这种情况,我该如何解决这个问题?
1个回答

5

您的退出菜单项“偶然”工作。它没有使用您实现的terminate(_:)方法。在那里放置一个print()语句,您会发现它没有被调用。

菜单项可以具有特定的目标对象或使用响应链搜索适当的目标。由于您没有为菜单项分配目标,因此它们正在使用响应链。您的MenuBarActions类不是响应链的一部分。(通常不能是类。某些对象可以是。)因此,菜单项永远不会针对您的类。

退出菜单能够正常工作是因为应用程序对象在响应链上,它具有terminate(_:)方法。实际上,如果您的terminate(_:)方法被调用了,它将调用该方法。但是菜单项实际上是直接调用它的。

您应该创建一个实际的控制器对象(而不仅仅是类),并将菜单项的target属性设置为它。


嗨,感谢您的见解。正如您所说,被调用的函数并不是我想象中的那个,我已经发现了响应者链 :) 然而,我还没有成功创建一个菜单项可以使用的控制器对象。您介意写一些示例代码吗? - Ire

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接