2012-07-12 9 views
5

Tengo un elemento de menú dentro del menú principal de la aplicación y me gustaría enrutar su acción a un controlador de vista (NSViewController). La jerarquía de la interfaz se ve así: hay un controlador de ventana de la aplicación principal por NSWindowController. Dentro de la ventana hay una vista dividida, y la vista derecha en la vista dividida está controlada por el NSViewController.¿Cómo enrutar acciones de menú a un NSViewController dentro de una ventana?

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

El elemento del menú está conectado a First Responder en el Interface Builder. El controlador de vista en cuestión implementa el método apropiado, pero el elemento del menú permanece desactivado. Cuando muevo el método al NSWindowController, el elemento del menú se habilita.

Pensé que tenía que llevar el controlador de vista a la cadena de respuesta, por lo que lo configuré como nextResponder para el controlador de ventana; sin cigarro ¿Qué estoy haciendo mal?

+0

Puede agregar un objeto en IB que represente a su Controlador. Luego, vincule la acción del menú a la IBAcción de su controlador. –

+0

Desafortunadamente eso no es posible, los controladores de visualización cambian de acuerdo con lo que se seleccionó en el panel de vista dividida izquierdo. – zoul

+0

Luego tendrá que reasignar la acción del menú cada vez que la vista se enfoque. Para acceder al menú: [[[[NSApp mainMenu] itemWithTitle: @ "ItemName"] menu] itemWithTitle @ "ItemName] setAction: @" Selector (theSelector)] –

Respuesta

3

Al final he añadido una clase base para mis controladores de ventana y lo hizo desviarán las llamadas a los controladores de los “niños”:

- (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; 
} 

Es una gran cantidad de código, pero es una solución general que mantiene el controlador código libre de reenvío ad-hoc. Espero que no sea mucha magia.

1

Puede configurar el controlador de ventana como el delegado de la ventana para que ahora forme parte de la cadena de respuesta.

Suponiendo que tiene su propia subclase de NSWindowController, puede simplemente capturar el evento de menú allí y llamar a los métodos apropiados en los controladores.

Desafortunadamente, los consejos contra el intento de insertar algo en la cadena de respuesta entre las diversas vistas y subvistas, por lo que no puede simplemente exprimir su controlador de vista allí.

Más here, pero entiendo que ya lo haya consultado.

Cuestiones relacionadas