2012-07-12 20 views
5

Ho una voce di menu all'interno del menu principale dell'app e mi piacerebbe indirizzare la sua azione a un controller di visualizzazione (NSViewController). La gerarchia dell'interfaccia è simile a questa: C'è un controller della finestra dell'app principale da uno NSWindowController. All'interno della finestra c'è una vista divisa e la vista destra nella vista divisa è controllata dal NSViewController.Come si indirizzano le azioni del menu a un NSViewController all'interno di una finestra?

Window + NSWindowController 
    `-- NSSplitView 
      `-- NSView 
      `-- NSView + NSViewController 

La voce di menu è collegata a First Responder in Interface Builder. Il controller di visualizzazione in questione implementa il metodo appropriato, ma la voce di menu rimane disabilitata. Quando sposto il metodo su NSWindowController, la voce di menu viene abilitata.

Ho capito che ho bisogno di ottenere il controller di visualizzazione sulla catena di risposta, quindi l'ho impostato come nextResponder per il controller della finestra; niente sigaro Che cosa sto facendo di sbagliato?

+0

È possibile aggiungere un oggetto in IB, che rappresenta il controller. Quindi collega l'azione del menu all'IBAction del tuo controller. –

+0

Sfortunatamente non è possibile, i controller della vista cambiano in base a ciò che è stato selezionato nel riquadro di visualizzazione divisa sinistra. – zoul

+0

Quindi dovrò ridefinire l'azione del menu ogni volta che la vista viene messa a fuoco. Per accedere al menu: [[[[[NSApp mainmenu] itemWithTitle: @ "ItemName"] menu] itemWithTitle @ "ItemName] setAction: @" Selector (theSelector)] –

risposta

3

Alla fine ho aggiunto una classe di base per i miei controllori finestra e ne ha fatto le chiamate in avanti per il “bambino” controllori:

- (id) childControllerForSelector: (SEL) selector 
{ 
    for (id controller in [childControllers copy]) 
     if ([controller respondsToSelector:selector]) 
      return controller; 
    return nil; 
} 

- (BOOL) respondsToSelector: (SEL) selector 
{ 
    return [super respondsToSelector:selector] ? YES : 
     [self childControllerForSelector:selector] ? YES : 
      NO; 
} 

- (void) forwardInvocation: (NSInvocation*) invocation 
{ 
    id child = [self childControllerForSelector:[invocation selector]]; 
    [invocation invokeWithTarget:child]; 
} 

- (NSMethodSignature*) methodSignatureForSelector: (SEL) selector 
{ 
    NSMethodSignature *signature = [super methodSignatureForSelector:selector]; 
    if (!signature) { 
     id child = [self childControllerForSelector:selector]; 
     signature = [child methodSignatureForSelector:selector]; 
    } 
    return signature; 
} 

E 'un sacco di codice, ma è una soluzione generale che mantiene il controller codice libero da inoltro ad-hoc. Spero che non sia troppa magia.

1

È possibile impostare il controller finestra come delegato della finestra in modo che ora faccia parte della catena di risposta.

Supponendo di avere la propria sottoclasse di NSWindowController, è possibile semplicemente catturare l'evento del menu e chiamare i metodi appropriati nei controller.

Sfortunatamente, i documenti sconsigliano di provare a inserire qualcosa nella catena di risposta tra le varie viste e sottoview, quindi non si può semplicemente spremere il controller di visualizzazione in là.

Altro here, ma suppongo che l'abbia già consultato.