2012-02-13 4 views
13

У меня есть подкласс NSView, и я бы хотел, чтобы он реагировал, когда пользователь нажимает кнопку ⇧ Shift. Однако -[NSView keyDown:] (который я сейчас переопределяю) не вызывается, когда нажаты только клавиши-модификаторы.Как я могу обнаружить, что нажата клавиша Shift?

Как я могу получить уведомление при нажатии клавиши Shift?

ответ

23

От события Cocoa обработки руководство:

flagsChanged: метод может быть полезен для обнаружение нажатия клавиш модификатора без одновременного нажатия любой другой клавиши. Например, если пользователь нажимает клавишу Option самостоятельно, ваш объект-ответчик может обнаружить это в своей реализации flagsChanged :.

Более подробную информацию можно найти here.

Документация NSResponder также утверждает следующее:

flagsChanged:

Сообщает получателю, что пользователь нажал или отпущена клавиши-модификатора (Shift, Control, и так далее).

- (Недействительными) flagsChanged: (NSEvent *) theEvent

+0

Похоже на то, что я хотел, я попробую. – zneak

-3

в документации Apple:

Вы должны override the keydown method

со следующим NSEvent modifier flags

+1

Я уже перекрывая 'метод keyDown' от' NSView' (в свою очередь, из 'NSResponder'), и метод просто не вызывается, когда я нажимаю клавишу shift. (Я обновил свой вопрос, чтобы отразить это, теперь я вижу, что это могло быть источником путаницы.) – zneak

+0

Вы посмотрели на ** Интерфейс управления интерфейсом ** **? Может быть, сдвиг даже без нажатия другой клавиши в то же время перехвачен им? Если вы нажмете shift + A, вы увидите, что нажата клавиша shift? – moxy

13

Вот пример, слегка модифицированный из ModKeyTest примера приложения Matt Джеммелл в. Создайте базовое приложение Cocoa с помощью одной кнопки и подключите кнопку к IBAction, как это. Затем попробуйте комбинацию клавиш. Документы немного нечеткие, но пример Мэтта очень ясен и представляет все, что вам нужно, чтобы использовать это дальше от документов.

- (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

Я думаю, что использование 'NSApp.currentEvent' является самым надежным решением, особенно при смешивании мыши и клавиатуры (например, Option-click) –

-2

Проверка нажатия:

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

Проверка выпуска:

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

Следует отметить, функция NSLog будет вызываться только если SHIFT, а затем другой нажата клавиша ,

Надеюсь, это поможет!

+0

Я боюсь, что это не так: это именно то, что я делал (за вопрос), и мне нужно было знать, не нажимая еще один ключ. – zneak

5

Вот код посвящен ключевым событием с быстрым 3.0.1 опробована на Xcode 8.2.1 и 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 ответа все теперь устарели. Помимо 'NSShiftKeyMask', также используется' NSAlphaShiftKeyMask' (см. Https://developer.apple.com/reference/appkit/nseventmodifierflags). Я заменяю первый на '.shift', но как насчет более позднего? Есть ли эквивалент Swift 3. – wcochran

+0

@wcochran Привет, согласно исходному коду Apple, в * AppKit.NSEvent.swift *, строка 307 (Xcode 8.2.1), '@available (OSX, введено: 10.0, устарело: 10.12, переименовано:" NSEventModifierFlags.capsLock ") public let NSAlphaShiftKeyMask: NSEventModifierFlags' Так что вместо этого используйте' .capsLock'. – longkai

Смежные вопросы