简体   繁体   English

我如何在可可中获取应用程序菜单

[英]How i can get the Application Menu in Cocoa

How can I get the NSMenu or NSMenuItem for the application menu (the one in the menu bar next to the apple menu). 如何获取应用程序菜单(Apple菜单旁边的菜单栏中的菜单)的NSMenu或NSMenuItem。 It seems to be automatically created and independent from the NSMenu I set via NSApplication setMainMenu. 它似乎是自动创建的,并且与我通过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

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]);
}

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. 根据我在OS X 10.11(El Capitan)和Xcode 7.1中的经验,复制该应用程序菜单并不难。 It seems Apple removed all the weird limitations. 苹果似乎消除了所有奇怪的限制。

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 . 您可以在此处下载工作示例。

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
   }

制作没有Xcode或IB的Cocoa应用程序对我来说是自虐的,但对他自己来说却是受虐狂的...尝试这个: [[[NSApp mainMenu] itemAtIndex: 0] submenu]

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

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