2012-02-13 320 views
13

我有一個NSView子類,我希望它在用戶按下⇧Shift鍵時作出反應。然而,-[NSView keyDown:](我當前覆蓋)僅在修改鍵被按下時才被調用。如何檢測按下Shift鍵?

如何在按下Shift鍵時得到通知?

回答

23

從可可事件處理指南:

的flagsChanged:方法可以是有用的在沒有任何其他鍵被同時按下的情況下檢測修改鍵的按下。例如,如果用戶自己按下Option鍵,您的響應者對象可以在其flagsChanged:的實現中檢測到這一點。

更多詳細信息可以參考here

NSResponder類的文件也指出以下:

flagsChanged:

通知接收用戶已按下或釋放修飾鍵(Shift鍵,控制,等)。

- (無效)flagsChanged:(NSEvent *)theEvent

+0

聽起來像我想要的,我會試試看。 – zneak 2012-02-13 22:00:26

-3
蘋果的文檔中

你必須override the keydown method

具有以下NSEvent modifier flags

+1

我已經從'NSView'重寫'keyDown'方法(反過來從'NSResponder'),並且當按下Shift鍵時,方法不會被調用。 (我更新了我的問題以反映這一點;我現在看到它可能是混淆的來源。) – zneak 2012-02-13 21:21:50

+0

你看過**鍵盤接口控制**部分嗎?也許在沒有同時按下其他按鍵的情況下被它截取?如果按下Shift + A,您是否看到按下Shift鍵? – moxy 2012-02-13 21:33:54

13

下面是一個例子,從馬特Gemmell的ModKeyTest示例應用程序稍微修改。 用一個按鈕創建一個基本的可可應用程序,並將按鈕連接到這樣的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'是最可靠的解決方案,尤其是當混合鼠標和鍵盤時(即單擊選項) – 2016-09-08 13:27:18

-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的功能纔會被調用,如果移位,然後其他一些鍵被按下。

希望這會有所幫助!

+0

恐怕不會:這就是*我正在做的事情(根據問題),而且我需要知道而不必按另一個鍵。 – zneak 2014-04-11 19:22:31

5

下面是代碼涉及關鍵事件上的Xcode 8.2.1和MacOS 10.12.2測試迅速3.0.1

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

現在已經不推薦使用預先快速回答的3個答案。除了'NSShiftKeyMask'外,還有一個'NSAlphaShiftKeyMask'(請參閱https://developer.apple.com/reference/appkit/nseventmodifierflags) - 我用'.shift'替換前者,但後來呢?有沒有一個Swift 3的等價物。 – wcochran 2017-04-03 18:02:20

+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 2017-04-03 19:28:32