2012-03-23 20 views
5

Tengo un NSTableView basado en la vista. Cada vista en la tabla tiene un campo de texto personalizado.mouseDown: en un NSTextField personalizado dentro de un NSTableView

Me gustaría iniciar una acción cuando el usuario hace clic en el campo de texto (etiqueta) dentro de la vista de la tabla (imagine tener un hipervínculo con una acción personalizada en cada celda de la tabla).

He creado una subclase básica NSTextField para capturar los eventos del mouse. Sin embargo, solo activan el segundo clic, no el primer clic.

Intenté usar un NSButton y eso se dispara enseguida.

Aquí es el código de la etiqueta personalizada:

@implementation HyperlinkTextField 

- (void)mouseDown:(NSEvent *)theEvent { 
    NSLog(@"link mouse down"); 
} 

- (void)mouseUp:(NSEvent *)theEvent { 
    NSLog(@"link mouse up"); 
} 

- (BOOL)acceptsFirstResponder { 
    return YES; 
} 

- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent { 
    return YES; 
} 
@end 

Respuesta

6

Resultó que NSTableViewNSOultineView y manejar el primer estado de respuesta para casos NSTextField diferente que para una NSButton.

La clave para hacer que la etiqueta responda al primer clic como un botón es sobrescribir [NSResponder validateProposedFirstResponder:forEvent:] para devolver YES en el caso de mi clase de campo de texto personalizado.

Documentación:

http://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSResponder_Class/Reference/Reference.html#//apple_ref/occ/instm/NSResponder/validateProposedFirstResponder:forEvent:

1

El comportamiento que se está viendo se debe a la vista de tabla es el primer nivel de respuesta, que debe ser o la fila no cambiará cuando se hace clic en la etiqueta: este es el comportamiento que un usuario espera al hacer clic en una fila de la tabla. En lugar de subclasificar la etiqueta, creo que sería mejor crear una subclase en la vista de tabla y reemplazar mouseDown: allí. Después de llamar a la implementación de mousedownown del super :, puedes hacer una prueba de impacto para verificar que el usuario hizo clic sobre la etiqueta.

@implementation CustomTable 

- (void)mouseDown:(NSEvent *)theEvent 
{ 
    [super mouseDown:theEvent]; 
    NSPoint point = [self convertPoint:theEvent.locationInWindow fromView:nil]; 
    NSView *theView = [self hitTest:point]; 
    if ([theView isKindOfClass:[NSTextField class]]) 
    { 
     NSLog(@"%@",[(NSTextField *)theView stringValue]); 
    } 
} 

@end 
+0

para reemplazar. Gracias, intentaré eso. Una pregunta: el primer clic funciona con un NSButton (la fila de la tabla no está seleccionada en ese caso). ¿Hay alguna forma de emular ese comportamiento? – Mark

+0

Probablemente exista, pero no lo sé. Pensé que devolver YES para acceptsFirstMouse y/o acceptFirstResponder lo hubiera hecho. – rdelmar

+0

Si quiere el comportamiento que obtiene con un botón, ¿por qué no simplemente usa un botón? Puede desactivar el borde, y se verá como una etiqueta sin bordes de todos modos. Si desea un borde, puede insertar un botón sin bordes en un NSBox. – rdelmar

7

tenía el mismo problema. La respuesta aceptada aquí no funcionó para mí. Después de muchas dificultades, mágicamente funcionó cuando seleccioné "Ninguno" en comparación con el predeterminado "Regular", con la otra opción como "Fuente de lista" para la opción "Resaltar" de la vista de tabla en IB.

Editar: La respuesta aceptada resulta engañosa ya que el método se sobrecargará para la vista de tabla y no para el campo de texto como lo sugiere la respuesta. Se da más claramente en https://stackoverflow.com/a/13579469/804616 pero en cualquier caso, ser más específico se siente un poco hacky.

+0

esto no funciona. tal vez hiciste algo más –

+2

parece que esto funciona en realidad. Estaba intentando activar mouseUp, pero eso no funciona con ninguno de los métodos. MouseDown funciona con ambos –

+0

Si bien esto funciona, ¿qué sucede si desea que la vista de tabla use el estilo de vista de tabla de la lista fuente? –

1

En la misma situación, integrar un NSButton con transparent establecido en true/YES funcionó para mí.

class LinkButton: NSTextField { 

    var clickableButton:NSButton? 

    override func viewDidMoveToSuperview() {    
     let button = NSButton() 
     self.addSubview(button) 

     //setting constraints to cover the whole textfield area (I'm making use of SnapKit here, you should add the constraints your way or use frames 
     button.snp_makeConstraints { (make) -> Void in 
      make.edges.equalTo(NSEdgeInsetsZero) 
     } 
     button.target = self 
     button.action = Selector("pressed:") 
     button.transparent = true 
    } 

    func pressed(sender:AnyObject) { 
     print("pressed") 
    } 
0

Utiliza window.makeFirstResponser (myTextfield) para comenzar a editar el campo de texto. Envía este mensaje desde el método mouseDown (con evento TheEvent: NSEvent)

Cuestiones relacionadas