如何获取应用程序菜单(即苹果菜单旁边的菜单栏中的那个)的NSMenu或NSMenuItem?它似乎是自动创建的,与我通过NSApplication setMainMenu设置的NSMenu无关。
顺便说一下:我正在构建我的完整应用程序,没有使用Xcode,请勿提供InterfaceBuilder提示。
PS:MacOSX 10.5
如果没有使用IB,您可以使用NSApplication的mainMenu访问菜单:
NSMenu *mainMenu = [[NSApplication sharedApplication] mainMenu];
NSMenu *appMenu = [[mainMenu itemAtIndex:0] submenu];
for (NSMenuItem *item in [appMenu itemArray]) {
NSLog(@"%@", [item title]);
}
虽然这是一个5年前的问题...但我想分享一下如何制作它。
在我的经验中,使用OS X 10.11(El Capitan)和Xcode 7.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()
无论如何,这不是自动生成的,我不得不自己设置它们。我不确定是否有其他方法可以做到这一点。
您可以在此处下载工作示例。
我对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)
}
}
}
....
for item in editMenu.items{
item.isEnabled = true
}
[[[NSApp mainMenu] itemAtIndex: 0] submenu]
。applicationDidFinishLaunching:
代理方法中尝试的。 - JWWalker