2010-08-08 9 views
10

Come posso ottenere NSMenu o NSMenuItem per il menu dell'applicazione (quello nella barra dei menu accanto al menu Apple). Sembra essere creato automaticamente e indipendente dal NSMenu I impostato tramite NSApplication setMainMenu.Come posso ottenere il menu dell'applicazione in cacao

A proposito: sto costruendo la mia domanda completa senza Xcode, quindi per favore non punte InterfaceBuilder.

PS: MacOSX 10.5

risposta

17

Senza IB, è possibile accedere al menu utilizzando mainMenu del NSApplication:

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

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

No, questo non funziona. numberOfItems in NSMenu mi dà anche 1 quando vedo chiaramente gli elementi "File TestMenu" nella barra dei menu. – Lothar

+0

Ah, mi sembra di aver ipotizzato la struttura del tuo progetto. Hai creato il progetto in XCode e poi rimosso completamente il pennino/xib? O stai andando completamente da zero? Questo post di blog parla di ciò che stai vivendo con il menu principale e di come potresti essere in grado di lavorare il tuo progetto in modo tale da ottenere il menu dell'applicazione: http://lapcatsoftware.com/blog/2007/05/16/working -without-a-nib-part-1/ –

+0

Grazie. E sì, sono completamente senza bacchette, infatti durante lo sviluppo corro addirittura come un normale programma ELF a.out senza una struttura Bundle. Funziona bene execept per il menu. – Lothar

0

Fare un'applicazione Cocoa, senza Xcode o IB suoni masochista a me, ma a ciascuno il suo ... Prova questo: [[[NSApp mainMenu] itemAtIndex: 0] submenu].

+0

Beh, sto scrivendo un linguaggio vincolante e voglio rimanere portatile sulla piattaforma. Ma la tua soluzione non funziona. La voce di menu con il nome del gruppo che viene generato automaticamente non fa parte del menu principale. – Lothar

+0

Ha funzionato per me, ma l'ho provato in una normale app con Xcode e IB. – JWWalker

+0

È possibile che lo abbia provato troppo presto nel processo di avvio dell'app? L'ho provato nel metodo 'applicationDidFinishLaunching:' delegate. – JWWalker

11

Anche se questo è di 5 anni domanda ... Mi piace condividere come farlo.

Nella mia esperienza in OS X 10.11 (El Capitan) con Xcode 7.1, non è difficile da replicare quel menu delle applicazioni. Sembra che Apple abbia rimosso tutte le strane limitazioni.

Nota: Questo codice viene aggiornato per Swift 3, e testato solo in 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() 

In ogni caso, non viene generato automaticamente, e ho dovuto impostare tutti in su me stesso. Non sono sicuro se ci sia un altro modo per farlo o no.

È possibile scaricare esempio here lavoro.

Problemi correlati