2010-08-08 2 views
10

Comment puis-je obtenir le NSMenu ou NSMenuItem pour le menu de l'application (celui de la barre de menu à côté du menu apple). Il semble être créé automatiquement et indépendant du menu NSMenu que j'ai défini via NSApplication setMainMenu. Par ailleurs: Je construis mon application complète sans Xcode, donc s'il vous plaît pas de conseils InterfaceBuilder.Comment puis-je obtenir le menu de l'application dans Cocoa

PS: MacOSX 10.5

Répondre

17

Sans IB, vous pouvez accéder au menu à l'aide du mainMenu NSApplication:

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

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

Non, cela ne fonctionne pas. numberOfItems dans NSMenu me donne aussi 1 quand je vois clairement les éléments "TestMenu File" dans la barre de menu. – Lothar

+0

Ah, j'ai l'air d'avoir fait une hypothèse sur la structure de votre projet. Avez-vous créé le projet en XCode, puis supprimez complètement le nib/xib? Ou allez-vous totalement à partir de zéro? Cette entrée de blog parle de ce que vous expérimentez avec le menu principal et de la façon dont vous pourriez travailler votre projet de manière à obtenir le menu de l'application: http://lapcatsoftware.com/blog/2007/05/16/working -without-a-nib-part-1/ –

+0

Merci c'est tout. Et oui, je suis complètement inoffensif, en fait, pendant le développement, je fonctionne même comme un programme ELF a.out normal sans une structure Bundle. Cela fonctionne bien sauf pour le menu. – Lothar

0

Faire une application Cocoa sans Xcode ou IB semble masochistes à moi, mais à chacun son propre ... Essayez ceci: [[[NSApp mainMenu] itemAtIndex: 0] submenu].

+0

Eh bien, j'écris une liaison de langue et je veux rester plate-forme portable. Mais votre solution ne fonctionne pas. L'élément de menu avec le nom de groupe généré automatiquement ne fait pas partie du menu principal. – Lothar

+0

Cela a fonctionné pour moi, mais je l'ai essayé dans une application normale avec Xcode et IB. – JWWalker

+0

Est-il possible que vous l'ayez essayé trop tôt dans le processus de démarrage de l'application? Je l'ai essayé dans la méthode 'applicationDidFinishLaunching:' delegate. – JWWalker

11

Bien que ce soit 5 ans question ... Je voudrais partager comment le faire.

Dans mon expérience dans OS X 10.11 (El Capitan) avec Xcode 7.1, il n'est pas difficile de répliquer ce menu de l'application. Il semble qu'Apple a supprimé toutes les limitations étranges.

Remarque: Ce code est mis à jour pour Swift 3 et testé uniquement dans 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() 

Quoi qu'il en soit, ce n'est pas généré automatiquement, et j'ai dû les configurer tous moi-même. Je ne suis pas sûr s'il y a une autre façon de le faire ou non.

Vous pouvez télécharger l'exemple de travail here.

Questions connexes