2012-02-13 20 views
13

Tengo una subclase NSView y me gustaría que reaccione cuando el usuario presiona la tecla ⇧ Shift. Sin embargo, -[NSView keyDown:] (que anulo actualmente) no se llama cuando se presionan las teclas de modificación solo.¿Cómo puedo detectar que se haya presionado la tecla Shift?

¿Cómo puedo recibir notificaciones cuando se presiona la tecla Shift?

Respuesta

23

Desde el caso del cacao manejo de guía:

El flagsChanged: método puede ser útil para detectar la presión de las teclas modificadoras sin presionar ninguna otra tecla simultáneamente. Por ejemplo, si el usuario presiona la tecla Opción por sí mismo, su objeto respondedor puede detectar esto en su implementación de flagsChanged :.

Más detalles se pueden encontrar here.

La documentación para NSResponder también afirma lo siguiente:

flagsChanged:

informa al receptor de que el usuario ha presionado o liberado una tecla de modificación (Shift, Control, y así sucesivamente).

- (void) flagsChanged: (NSEvent *) TheEvent

+0

Suena como lo que quería, lo intentaré. – zneak

-3

en la documentación de la manzana:

Tienes que override the keydown method

con la siguiente NSEvent modifier flags

+1

Ya estoy reemplazando el método '' keyDown' de NSView' (a su vez de 'NSResponder') y el método simplemente no se llama cuando presiono la tecla shift. (Actualicé mi pregunta para reflejar esto; ahora veo que podría haber sido una fuente de confusión.) – zneak

+0

¿miró la parte ** Control de interfaz de teclado **? ¿Quizás el cambio incluso sin otra tecla presionada al mismo tiempo es interceptado por él? Si presiona Mayús + A, ¿ve presionada la tecla Mayús? – moxy

13

Aquí es un ejemplo, modificada ligeramente de aplicación de ejemplo ModKeyTest de Matt Gemmell. Crea una aplicación básica Cocoa con un botón y conecta el botón a un IBAction como este. Luego pruebe la combinación de teclas que desee. Los documentos son un poco confusos, pero el ejemplo de Matt es muy claro y presenta todo lo que necesita para aprovechar esto más allá de los documentos.

- (IBAction)myAction:(id)sender { 
NSUInteger flags = [[NSApp currentEvent] modifierFlags]; 
if ((flags & NSCommandKeyMask) && (flags & NSAlternateKeyMask) && (flags & NSControlKeyMask)) { 
    NSBeginInformationalAlertSheet(@"Modifier keys Command Option Control detected", nil, nil, nil, [NSApp mainWindow], self, nil, nil, nil, 
            @"You sneaky thing!"); 
} 

if ((flags & NSCommandKeyMask) && (flags & NSShiftKeyMask)) { 
    NSBeginInformationalAlertSheet(@"Modifier keys Command Shift detected", nil, nil, nil, [NSApp mainWindow], self, nil, nil, nil, 
            @"You sneaky thing!"); 
} 

if ((flags & NSAlphaShiftKeyMask)) { 
    NSBeginInformationalAlertSheet(@"Modifier keys Caps Lock detected", nil, nil, nil, [NSApp mainWindow], self, nil, nil, nil, 
            @"You sneaky thing!"); 
} 
if ((flags & NSFunctionKeyMask)) { 
    NSBeginInformationalAlertSheet(@"Modifier keys fn detected", nil, nil, nil, [NSApp mainWindow], self, nil, nil, nil, 
            @"You sneaky thing!"); 
} 
+0

Creo que usar 'NSApp.currentEvent' es la solución más confiable, especialmente cuando se mezcla el mouse y el teclado (es decir, Opción-clic) –

-2

Comprobación de prensado:

-(void)keyDown:(NSEvent *)theEvent 
{ 
    if ([theEvent modifierFlags] & NSShiftKeyMask) 
    { 
     NSLog("Shift key was pressed"); 
    } 
} 

Comprobación de liberación:

-(void)keyUp:(NSEvent *)theEvent 
{ 
    if(!([theEvent modifierFlags] & NSShiftKeyMask)) 
    { 
     NSLog("Shift key was released"); 
    } 
} 

Cabe destacar, la función NSLog sólo se llama si y luego se pulsa otra tecla SHIFT .

Espero que esto ayude!

+0

Me temo que no: esto es * exactamente * lo que estaba haciendo (según la pregunta), y necesitaba saber sin tener que presionar otra tecla. – zneak

5

Aquí está el Código trata evento clave con rapidez 3.0.1 probado en Xcode 8.2.1 y MacOS 10.12.2

override func keyDown(with event: NSEvent) { 
    var handled = false 
    if event.keyCode == 53 { // ESC, same as `CMD + .` 
     handled = true 
     print("ESC") 
    } 
    if event.modifierFlags.contains(.command) { // .shift, .option, .control ... 
     if let chars = event.charactersIgnoringModifiers { 
      handled = true // likely we are interested with that key 
      switch chars { 
      case "r": 
       print("CMD + r") 
      case ",": 
       print("CMD + ,") 
      case "/": 
       print("CMD + /") 
      default: 
       handled = false 
      } 
     } 
    } 
    if !handled { 
     super.keyDown(with: event) // let system handle it(may contains sound) 
    } 
} 
+0

Pre-Swift 3 respuestas ahora están en desuso. Además de 'NSShiftKeyMask' también solía haber un' NSAlphaShiftKeyMask' (ver https://developer.apple.com/reference/appkit/nseventmodifierflags) - Estoy reemplazando el primero con '.shift', pero ¿y el último? ¿Hay un equivalente de Swift 3? – wcochran

+0

@wcochran Hola, de acuerdo con el código fuente de Apple, en AppKit.NSEvent.swift * *, línea 307 (Xcode 8.2.1), '@available (OSX, introducida: 10,0, en desuso: 10.12, rebautizado: "NSEventModifierFlags.capsLock ") public let NSAlphaShiftKeyMask: NSEventModifierFlags' Así que use' .capsLock' en su lugar. – longkai

Cuestiones relacionadas