2011-09-25 26 views
10

Tengo una subclase NSView que es parte de un archivo .xib de una subclase NSDocument, que se activa por el comportamiento predeterminado del método NSDocumentControlleropenDocument:. En esta subclase NSView he implementado los métodos awakeFromNib, en los que se llama al método de la vista NSWindowsetAcceptsMouseMovedEvents:YES, y acceptsFirstMouse:, que devuelve YES. Pero mi implementación de método mouseMoved: de mi subclase NSView no se llama cuando muevo el mouse sobre ella. ¿Cuál podría ser el problema?mouseMoved no se llama

+0

Dependiendo de su caso de uso, es posible que pueda utilizar mouseDragged. Eso funciona sin un NSTrackingArea, pero solo se activa si el mouse está inactivo. –

Respuesta

10

No he usado mouseMoved: en un proyecto real (he jugado un poco con él un poco). Hasta donde puedo decir, solo se llama al mouseMoved: cuando su vista es la primera que responde y luego no solo mientras el mouse está sobre su vista, sino siempre cuando se mueve el mouse. Tal vez sea mejor usar un NSTrackingArea. Consulte Cocoa Event Handling Guide para obtener más información.

+0

Esto no responde la pregunta realmente. – uchuugaka

+0

Ver a continuación. Necesita instalar un área de seguimiento para comenzar a recibir estos eventos. – uchuugaka

19

Asegúrese de solicitar el evento se envía mouseMoved:

NSTrackingAreaOptions options = (NSTrackingActiveAlways | NSTrackingInVisibleRect | 
         NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved); 

NSTrackingArea *area = [[NSTrackingArea alloc] initWithRect:[self bounds] 
                options:options 
                 owner:self 
                userInfo:nil]; 
+0

Una nota. No estoy seguro de que deba ser un int, sino más bien un tipo NSInteger o typedef, preferiblemente NSTrackingAreaOptions, que es infinitamente más legible y está garantizado que es el tipo correcto. – uchuugaka

+0

esta es la respuesta correcta en realidad –

1

Sólo en caso cualquier otra persona se encuentra con esto. Me encontré con un problema donde estaba subclases una subclase y estaba tratando de agregar un área de seguimiento a ambas clases (por dos razones diferentes).

Si está haciendo algo como esto, deberá asegurarse de que su mouseMoved:, etc. llame al súper, o solo una de sus subclases recibirá el mensaje.

- (void) mouseMoved: (NSEvent*) theEvent 
{ 
    // Call the super event 
    [super mouseMoved: theEvent]; 
} 
2

Como han dicho otros, un NSTrackingArea es una buena solución, y un lugar apropiado para instalar el área de seguimiento es NSView.updateTrackingAreas(). No es necesario establecer la propiedad setAcceptsMouseMovedEvents que contiene NSWindow.

En Swift 3:

class CustomView : NSView { 

    var trackingArea : NSTrackingArea? 

    override func updateTrackingAreas() { 
     if trackingArea != nil { 
      self.removeTrackingArea(trackingArea!) 
     } 
     let options : NSTrackingAreaOptions = 
      [.activeWhenFirstResponder, .mouseMoved ] 
     trackingArea = NSTrackingArea(rect: self.bounds, options: options, 
             owner: self, userInfo: nil) 
     self.addTrackingArea(trackingArea!) 
    } 

    override func mouseMoved(with event: NSEvent) { 
     Swift.print("Mouse moved: \(event)") 
    } 
}