macos 我如何获得 Cocoa 中的应用程序菜单

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3436395/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 07:07:42  来源:igfitidea点击:

How i can get the Application Menu in Cocoa

cocoamacosnsmenu

提问by Lothar

How can I get the NSMenu or NSMenuItem for the application menu (the one in the menu bar next to the apple menu). It seems to be automatically created and independent from the NSMenu I set via NSApplication setMainMenu.

如何获取应用程序菜单(苹果菜单旁边的菜单栏中的菜单)的 NSMenu 或 NSMenuItem。它似乎是自动创建的,独立于我通过 NSApplication setMainMenu 设置的 NSMenu。

By the way: I'm building my complete application without Xcode, so please no InterfaceBuilder tips.

顺便说一句:我正在构建我没有 Xcode 的完整应用程序,所以请不要使用 InterfaceBuilder 提示。

PS: MacOSX 10.5

PS:MacOSX 10.5

回答by Jarret Hardie

Without IB, you can access the menu using the NSApplication's mainMenu:

如果没有 IB,您可以使用 NSApplication 的 mainMenu 访问菜单:

NSMenu *mainMenu = [[NSApplication sharedApplication] mainMenu];
NSMenu *appMenu = [[mainMenu itemAtIndex:0] submenu];

for (NSMenuItem *item in [appMenu itemArray]) {
    NSLog(@"%@", [item title]);
}

回答by Eonil

Though this is 5 years old question... I like to share how to make it.

虽然这是 5 年前的问题......我喜欢分享如何制作它。

In my experience in OS X 10.11 (El Capitan) with Xcode 7.1, it's not hard to replicate that application menu. It seems Apple removed all the weird limitations.

根据我在 OS X 10.11 (El Capitan) 和 Xcode 7.1 中的经验,复制该应用程序菜单并不难。苹果似乎删除了所有奇怪的限制。

Note: This code is updated for Swift 3, and tested only in macOS Sierra (10.12.1).

注意:此代码针对 Swift 3 进行了更新,并且仅在 macOS Sierra (10.12.1) 中进行了测试。

//
//  AppDelegate.swift
//  Editor6MainMenuUI2Testdrive
//
//  Created by Hoon H. on 2016/11/05.
//  Copyright ? 2016 Eonil. All rights reserved.
//

import Cocoa

/// You SHOULD NOT use `@NSApplicationMain` 
/// to make your custom menu to work.
class AppDelegate: NSObject, NSApplicationDelegate {
    func applicationDidFinishLaunching(_ aNotification: Notification) {}
    func applicationWillTerminate(_ aNotification: Notification) {}
}

func makeMainMenu() -> NSMenu {
    let mainMenu            = NSMenu() // `title` really doesn't matter.
    let mainAppMenuItem     = NSMenuItem(title: "Application", action: nil, keyEquivalent: "") // `title` really doesn't matter.
    let mainFileMenuItem    = NSMenuItem(title: "File", action: nil, keyEquivalent: "")
    mainMenu.addItem(mainAppMenuItem)
    mainMenu.addItem(mainFileMenuItem)

    let appMenu             = NSMenu() // `title` really doesn't matter.
    mainAppMenuItem.submenu = appMenu

    let appServicesMenu     = NSMenu()
    NSApp.servicesMenu      = appServicesMenu

    appMenu.addItem(withTitle: "About Me", action: nil, keyEquivalent: "")
    appMenu.addItem(NSMenuItem.separator())
    appMenu.addItem(withTitle: "Preferences...", action: nil, keyEquivalent: ",")
    appMenu.addItem(NSMenuItem.separator())
    appMenu.addItem(withTitle: "Hide Me", action: #selector(NSApplication.hide(_:)), keyEquivalent: "h")
    appMenu.addItem({ () -> NSMenuItem in
        let m = NSMenuItem(title: "Hide Others", action: #selector(NSApplication.hideOtherApplications(_:)), keyEquivalent: "h")
        m.keyEquivalentModifierMask = [.command, .option]
        return m
        }())
    appMenu.addItem(withTitle: "Show All", action: #selector(NSApplication.unhideAllApplications(_:)), keyEquivalent: "")

    appMenu.addItem(NSMenuItem.separator())
    appMenu.addItem(withTitle: "Services", action: nil, keyEquivalent: "").submenu = appServicesMenu
    appMenu.addItem(NSMenuItem.separator())
    appMenu.addItem(withTitle: "Quit Me", action: #selector(NSApplication.terminate(_:)), keyEquivalent: "q")

    let fileMenu = NSMenu(title: "File")
    mainFileMenuItem.submenu = fileMenu
    fileMenu.addItem(withTitle: "New...", action: #selector(NSDocumentController.newDocument(_:)), keyEquivalent: "n")

    return mainMenu
}

let del = AppDelegate()
/// Setting main menu MUST be done before you setting app delegate.
/// I don't know why.
NSApplication.shared().mainMenu = makeMainMenu()
NSApplication.shared().delegate = del
NSApplication.shared().run()

Anyway, it is not being generated automatically, and I had to set them all up myself. I am not sure whether there is another way to do this or not.

无论如何,它不是自动生成的,我必须自己设置它们。我不确定是否有另一种方法可以做到这一点。

You can download working example here.

您可以在此处下载工作示例。

回答by ingconti

my two cents for Swift 5.0

我 Swift 5.0 的两分钱

private final func manageMenus(){
    let  mainMenu =  NSApplication.shared.mainMenu

    if let editMenu = mainMenu?.item(at: 1)?.submenu{
        for item in editMenu.items{
            print(item.title)
        }
    }
}

so You can also enable it:

所以你也可以启用它:

....

....

  for item in editMenu.items{
       item.isEnabled = true
   }

回答by JWWalker

Making a Cocoa app without Xcode or IB sounds masochistic to me, but to each his own... Try this: [[[NSApp mainMenu] itemAtIndex: 0] submenu].

制作可可应用程序没有的Xcode或IB听起来自虐给我,但每一个他自己...试试这个:[[[NSApp mainMenu] itemAtIndex: 0] submenu]