简体   繁体   English

菜单项在macOS菜单栏App中禁用

[英]menu items disabled in macOS menubar App

I'm trying to build a menubar app on macOS. 我正在尝试在macOS上构建一个菜单栏应用程序。

I can't seem to figure out why some menu items are disabled... Screenshot: 我似乎无法弄清楚为什么一些菜单项被禁用...截图:

该应用的屏幕截图

As you can see, the Quit menu item is enabled, and quits the app when clicked. 如您所见, Quit菜单项已启用,并在单击时退出应用程序。 The Preferences item is disabled however. 但是, “首选项”项已禁用。

My code 我的代码

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

I am using the exact same way to create both MenuBarItems and the same structure for the selectors, so I am a little confused by this inconsistency. 我使用完全相同的方式为选择器创建MenuBarItems和相同的结构,所以我对这种不一致感到有些困惑。 What is the reason this happens and how can I solve this problem? 这种情况发生的原因是什么?如何解决这个问题?

Your Quit menu item is working "accidentally". 您的退出菜单项“意外”工作。 It is not using the terminate(_:) method you implemented. 它没有使用您实现的terminate(_:)方法。 Put a print() statement there and you'll see it's not being invoked. 在那里放一个print()语句,你会发现它没有被调用。

A menu item either has a specific target object assigned or it uses the responder chain to search for an appropriate target. 菜单项要么指定了特定的目标对象,要么使用响应程序链来搜索适当的目标。 You are not assigning a target for your menu items, so they are using the responder chain. 您没有为菜单项指定目标,因此他们正在使用响应程序链。 Your MenuBarActions class is not part of the responder chain. 您的MenuBarActions 不是响应者链的一部分。 (Classes generally can't be. Certain objects can be.) So, the menu items will never target your class. (类通常不能。某些对象可以。)因此,菜单项永远不会以您的类为目标。

The Quit menu works because the application object is on the responder chain and it has a terminate(_:) method. Quit菜单有效,因为应用程序对象位于响应程序链上,并且它具有terminate(_:)方法。 In fact, that's what your terminate(_:) method would invoke if it were ever being called. 实际上,这就是你的terminate(_:)方法在被调用时会调用的内容。 But the menu item is actually invoking it directly. 但菜单项实际上是直接调用它。

You should create an actual controller object (not just class) that implements the action methods and set the menu items' target property to it. 您应该创建一个实际的控制器对象(不仅仅是类)来实现操作方法,并将菜单项的target属性设置为它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM