2011-09-25 10 views
10

Ho una sottoclasse NSView che fa parte di un file .xib di una sottoclasse NSDocument, che diventa attiva con il comportamento predefinito del metodo . In questa sottoclasse NSView ho implementato i metodi awakeFromNib, in cui viene chiamato il metodo NSWindowsetAcceptsMouseMovedEvents:YES della vista e acceptsFirstMouse:, che restituisce YES. Ma l'implementazione del metodo mouseMoved: della sottoclasse NSView non viene chiamata quando si sposta il mouse su di essa. Quale potrebbe essere il problema?mouseMoved non chiamato

+0

A seconda del caso d'uso, si può essere in grado di utilizzare mouseDragged. Funziona senza NSTrackingArea, ma si attiva solo se il mouse non funziona. –

risposta

10

Non ho usato mouseMoved: in un progetto reale (ci ho giocato un po '). Per quanto posso dire, mouseMoved: viene chiamato solo quando la tua vista è la prima a rispondere e quindi non solo mentre il mouse è sopra la tua vista, ma sempre quando il mouse si muove. Potrebbe essere meglio usare NSTrackingArea. Controllare lo Cocoa Event Handling Guide per ulteriori informazioni.

+0

Questo non risponde alla domanda davvero. – uchuugaka

+0

Vedi sotto. È necessario disporre di un'area di tracciamento installata per iniziare a ricevere questi eventi. – uchuugaka

19

Assicuratevi di richiedere l'evento mouseMoved viene inviato:

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

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

Una nota. Non sono sicuro che dovrebbe essere un int ma piuttosto un tipo NSInteger o il typedef preferibilmente NSTrackingAreaOptions che è infinitamente più leggibile e garantito per essere il tipo giusto. – uchuugaka

+0

questa è la risposta corretta in realtà –

1

Solo in caso chiunque altro si imbatte in questo. Mi sono imbattuto in un problema in cui stavo sottoclassi una sottoclasse e stavo cercando di aggiungere un'area di tracciamento ad entrambe le classi (per due diversi motivi).

Se si sta facendo qualcosa del genere, è necessario assicurarsi che il proprio mouseMoved:, ecc. Chiami nel super o solo una delle sottoclassi riceverà il messaggio.

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

Come notato da altri, un NSTrackingArea è una buona soluzione, e un luogo adatto per l'installazione nella zona di monitoraggio è NSView.updateTrackingAreas(). Non è necessario impostare la proprietà setAcceptsMouseMovedEvents contenente NSWindow.

In 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)") 
    } 
}