2012-09-04 30 views
5

Tengo un problema con un NSTableView basado en vista que se ejecuta en 10.8 (el objetivo es 10.7, pero creo que esto no es relevante).Cómo desencadenar una acción desde un NSTableCellView en vista basado en NSTableView al utilizar enlaces

Estoy usando un NSTableView, y obtengo valores de contenido para mis enlaces NSTableCellView personalizados a través de. Uso el obejctValue de NSTableCellView para obtener mis datos.

Agregué un botón a mi celular, y me gustaría que actuara al hacer clic. Hasta ahora solo he podido activar una acción dentro de la subclase personalizada de NSTableCellView.

puedo conseguir la fila que se hizo clic como este, usando la cadena:

NSButton *myButton = (NSButton*)sender;  

NSTableView *myView = (NSTableView*)myButton.superview.superview.superview; 

NSInteger rowClicked = [myView rowForView:myButton.superview]; 

A partir de ahí no sé cómo llegar a mi delegado de la aplicación o el controlador donde se define la acción.

Como estoy utilizando enlaces de cacao, no tengo un delegado en NSTableView que pueda usar para activar mi acción.

¿Tiene alguna idea de cómo podría responder al controlador?

¡Muchas gracias de antemano!

Respuesta

2

Aunque está utilizando enlaces, aún puede configurar su controlador como delegado para su vista de tabla en el constructor de interfaz.

Veo que ya puede acceder a la vista de tabla desde el interior de su celda. La siguiente tarea debe ser simple, simplemente configure el delegado de la vista de tabla como el objetivo para la acción de su botón.

+0

Gracias, lo encontré de la manera que dijiste. En realidad estaba desconcertado al principio al tener que suministrar la celda. Pero funciona bien. –

3

Gracias por su pregunta, también voy a activar una acción desde un botón en un NSTableView. Tu pregunta me ayudó a ponerme en el camino correcto.

Primero, para solucionar el problema de encontrar el número de fila en el que está mi NSTableView. Yo era capaz de encontrarlo sin conocer el botón, en mi costumbre NSTableView he instalado el siguiente como un primer intento:

- (NSInteger)myRowNumber 
{ 
    return [(NSTableView*)self.superview.superview rowForView:self]; 
} 

esto funciona bien, sin embargo, es menos robusto. Solo funciona si ya sabes específicamente qué tan profundo eres en la jerarquía de vistas. Una solución más robusta y universal es:

- (NSInteger)myRowNumber 
{ 
    NSTableView* tableView = nil; 
    NSView* mySuperview = self; 

    do 
    { 
     NSView* nextSuper = mySuperview.superview; 
     if (nextSuper == nil) 
     { 
      NSException *exception = 
       [NSException exceptionWithName:@"NSTableView not found." 
        reason:[NSString stringWithFormat:@"%@ search went too deep.", 
        NSStringFromSelector(_cmd)] userInfo:nil]; 
      @throw exception; 
     } 

     if ([nextSuper isKindOfClass:[NSTableView class]]) 
      tableView = (NSTableView*)nextSuper; 
     else 
      mySuperview = mySuperview.superview; 
    } while (tableView == nil); 

    return [tableView rowForView:self]; 
} 

esto no sólo funciona a nivel NSTableView, pero funciona con cualquier cosa instalada en cualquier nivel por encima de ella, independientemente de la complejidad de la jerarquía de vistas.

En cuanto a la parte no respondida de su pregunta, establecí un IBOutlet en mi clase y utilizando el constructor de interfaces vinculado si al propietario de mi archivo (en mi caso mi clase de documento). Una vez que tuve una referencia a la clase a la que estaba enviando mi mensaje, y el número de fila, llamé a la función. En mi caso, la llamada requería que pasara el número de fila del que proviene.

[self.myDoc doSomethingToRow:self.myRowNumber]; 

He probado esto y funciona en varios niveles de la jerarquía de vista por encima de NSTableView. Y funciona sin tener que tener primero la fila seleccionada (que parece asumirse en la documentación de Apples).

cordiales, George Lawrence de tormenta, Maltby, Washington, EE.UU.

1

Use rowForView: y la cadena de respuesta

Para responder a la acción de un control embebido dentro de una NSTableCellView, el control debe emitir la acción a la Primera Respondedor. Alternativamente, File Owner es posible pero está más estrechamente acoplado.

Uso rowForView: dentro del método de acción para determinar qué de fila de control emitió la acción:

- (IBAction)revealInFinder:(id)sender { 
    NSInteger row = [self.tableView rowForView:sender]; 
    ... 
} 

La acción se implementa dentro de cualquiera de las clases de cadena respondedor. Lo más probable es que esta sea su instancia de NSWindowController subclasificada. El respondedor también podría ser el delegado de la aplicación; asumiendo que el delegado tiene un medio para hablar con el NSTableView.

Consulte el ejemplo de Apple TableViewPlayground: Using View-Based NSTableView and NSOutlineView para ver esto en acción.

Cuestiones relacionadas