2012-02-13 117 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