如何在Mac Cocoa App中实现快捷键输入?

Vic*_*kov 10 macos shortcuts cocoa objective-c

我需要在我的Cocoa App中创建一个全局热键输入框.

我知道Shortcut Recorder,但它是一个非常古老的解决方案.它有使用Carbon实现的部分,已被弃用,如果我使用它,我无法将我的应用程序发布到Mac App Store.

有现成的现代解决方案吗?任何人都可以给我自己的方式(我不知道从哪里开始)?

Vad*_*dim 14

有一个名为MASShortcut的现代框架,用于在OS X 10.7+中实现全局快捷方式.

  • (他建造的)< - 并不是说​​有什么问题,但应该是透明的 (6认同)

kia*_*uno 13

在Mac OS X 10.6及更高版本中,您可以使用方法+ addGlobalMonitorForEventsMatchingMask:handler:+ addLocalMonitorForEventsMatchingMask:handler:NSEvent类中定义.监控事件报告以下信息:

本地和全球事件监视器是互斥的.例如,全局监视器不会观察安装它的应用程序的事件流.本地事件监视器仅观察其应用程序的事件流.要监视来自所有应用程序(包括"当前"应用程序)的事件,您必须安装两个事件监视器.

该页面中显示的代码用于本地事件监视器,但全局事件监视器的代码类似; 调用NSEvent的方法有什么变化.

_eventMonitor = [NSEvent addLocalMonitorForEventsMatchingMask:
        (NSLeftMouseDownMask | NSRightMouseDownMask | NSOtherMouseDownMask | NSKeyDownMask)
        handler:^(NSEvent *incomingEvent) {
    NSEvent *result = incomingEvent;
    NSWindow *targetWindowForEvent = [incomingEvent window];
    if (targetWindowForEvent != _window) {
        [self _closeAndSendAction:NO];
    } else if ([incomingEvent type] == NSKeyDown) {
        if ([incomingEvent keyCode] == 53) {
            // Escape
            [self _closeAndSendAction:NO];
            result = nil; // Don't process the event
        } else if ([incomingEvent keyCode] == 36) {
            // Enter
            [self _closeAndSendAction:YES];
            result = nil;
        }
    }
    return result;
}];
Run Code Online (Sandbox Code Playgroud)

一旦监视器不再需要,您可以使用以下代码将其删除:

[NSEvent removeMonitor:_eventMonitor];
Run Code Online (Sandbox Code Playgroud)

  • 这不适用于关键事件,除非该应用程序受信任可访问性 (4认同)
  • 另一个需要注意的问题是,使用这种方法的一些按键命令仍然会触发“Funk”错误声音。有谁知道有什么方法可以阻止这种情况吗? (2认同)

Pet*_*sey 13

并非所有Carbon都被弃用.你不能再制作一个纯碳应用程序了,但有些API仍在使用,其中一些仍然是做某些事情最简单的方法.

其中之一是Carbon Events热键API.您当然可以使用NSEvent的事件监视器方法筛选所有事件,但这是不必要的工作.Carbon Events热键API仍然受支持且更简单 - 您只需告诉它要匹配的键和按下键时要调用的函数.还有像DDHotKey这样的Cocoa包装器使它更简单.