Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift macOS菜单栏应用程序中禁用的菜单项_Swift_Macos_Swift3 - Fatal编程技术网

Swift macOS菜单栏应用程序中禁用的菜单项

Swift macOS菜单栏应用程序中禁用的菜单项,swift,macos,swift3,Swift,Macos,Swift3,我正在尝试在macOS上构建一个菜单栏应用程序 我似乎不明白为什么有些菜单项被禁用。。。截图: 如您所见,退出菜单项已启用,单击时退出应用程序。但是,首选项被禁用 我的代码 AppDelegate.swift: let menuBarItem = NSStatusBar.system().statusItem(withLength: NSSquareStatusItemLength) func applicationDidFinishLaunching(_ aNotification: No

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

我似乎不明白为什么有些菜单项被禁用。。。截图:

如您所见,退出菜单项已启用,单击时退出应用程序。但是,首选项被禁用

我的代码
AppDelegate.swift:

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

func applicationDidFinishLaunching(_ aNotification: Notification) {
    menuBarItem.button?.image = NSImage(named: "MenuBarIcon")
    menuBarItem.menu = MenuBarMenu()
}
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")
    }
}
MenuBarMenu.swift:

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

func applicationDidFinishLaunching(_ aNotification: Notification) {
    menuBarItem.button?.image = NSImage(named: "MenuBarIcon")
    menuBarItem.menu = MenuBarMenu()
}
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")
    }
}

我使用完全相同的方法来创建menubaritem和选择器的相同结构,因此我对这种不一致性有点困惑。发生这种情况的原因是什么?如何解决此问题?

您的“退出”菜单项“意外”工作。它没有使用您实现的
terminate(:)
方法。在那里放一个
print()
语句,您将看到它没有被调用

菜单项要么指定了特定的目标对象,要么使用响应器链搜索适当的目标。您没有为菜单项指定目标,因此它们使用响应器链。您的
菜单操作
类不是响应程序链的一部分。(类通常不能是。某些对象可以是。)因此,菜单项永远不会以类为目标

“退出”菜单之所以有效,是因为应用程序对象位于响应程序链上,并且它有一个
terminate(:)
方法。事实上,如果调用了
terminate(:)
方法,它就会调用这个函数。但是菜单项实际上是直接调用它


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

Hi,感谢您的帮助。正如您所说,被调用的函数不是我所认为的函数,我发现了响应器链:)但是,我还没有创建MenuItems可以使用的控制器对象。你介意写一些示例代码吗?