Mac Catalyst 无法使用 pressesBegan 覆盖捕获 .command 键修饰符

Posted

技术标签:

【中文标题】Mac Catalyst 无法使用 pressesBegan 覆盖捕获 .command 键修饰符【英文标题】:Mac Catalyst cannot capture .command key modifier with pressesBegan override 【发布时间】:2021-01-25 01:01:12 【问题描述】:

我正在为 ios(以及通过 Mac Catalyst 的 MacOS)开发一个远程桌面控制应用程序,该应用程序必须能够捕获设备上的所有键盘输入,包括 Cmd 键(相当于非 Mac 键盘上的 Super / Start 键)应用程序位于前台,以便将它们发送到远程桌面。

我还没有尝试查看带有外部键盘的 iOS 设备是否看到 .command 键修饰符,但是当我启用 Mac Catalyst 支持并在我的 Mac 上安装应用程序并将以下方法添加到 AppDelegate 时:

    override func pressesBegan(_ presses: Set<UIPress>,
                           with event: UIPressesEvent?) 
    super.pressesBegan(presses, with: event)
    print(presses.first?.key, presses.first?.key?.modifierFlags)

override func pressesEnded(_ presses: Set<UIPress>,
                           with event: UIPressesEvent?) 
    super.pressesEnded(presses, with: event)
    print(presses.first?.key, presses.first?.key?.modifierFlags)

override func pressesCancelled(_ presses: Set<UIPress>,
                               with event: UIPressesEvent?) 
    super.pressesCancelled(presses, with: event)
    print(presses.first?.key, presses.first?.key?.modifierFlags)

我几乎可以捕获我尝试的任何组合键,除非 Cmd/Start/Super 键也在组合键中。当 Cmd 键在组合键中或单独按下时,绝对不会向应用程序发送任何内容。该事件似乎完全由 Mac OS X 保留和使用。

为了这篇文章的完整性,我想补充一点,我也尝试从应用程序中删除所有菜单,以防万一菜单是消耗 Cmd 键事件的罪魁祸首,但没有任何改变:

    override func buildMenu(with builder: UIMenuBuilder) 
    if builder.system == .main 
        builder.remove(menu: .edit)
        builder.remove(menu: .format)
        builder.remove(menu: .help)
        builder.remove(menu: .file)
        builder.remove(menu: .window)
        builder.remove(menu: .view)
        let dummyCommand = UICommand(title: "Dummy",
                  action: #selector(dummy),
                  discoverabilityTitle: "dummy")
        let mainMenu = UIMenu(title: "Dummy", image: nil, identifier: UIMenu.Identifier("dummy"), options: .displayInline, children: [dummyCommand])
        builder.replace(menu: .application, with: mainMenu)
    

我也尝试将应用程序置于全屏模式,但无济于事。

关于如何捕获 .command 修饰符的任何其他建议?

接下来我将尝试通过 AppKit 包捕获输入,但这并不理想。

非常感谢!

【问题讨论】:

【参考方案1】:

希望您已经有了答案,但万一没有: 您将需要使用如下代码检查印刷机

override func pressesBegan(_ presses: Set<UIPress>, with event: UIPressesEvent?) 

    var didHandleEvent : Bool = true
    print("presses began \(presses.count)")
    for press in presses 
        guard let key = press.key else  continue 

        if key.modifierFlags.contains(.command) 
            commandDown = true
            print("commandDown")
        
     ...

如果您希望系统在您的代码之外处理按键,您也应该只调用 super.pressesBegan。在您的情况下,我怀疑您不希望系统执行此操作,因此请跟踪您处理过的印刷机,只有在未处理的情况下才会调用 super。 您可能还希望将您的视图控制器设置为.becomeFirstResponder() (假设您使用的是 UIVIewController )

【讨论】:

以上是关于Mac Catalyst 无法使用 pressesBegan 覆盖捕获 .command 键修饰符的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 Xcode 成功签署 Mac Catalyst 应用程序

如何在 Mac 上的 Mac Catalyst 应用程序中使用钥匙串?

无法将 iPad 应用程序转换为 Mac 应用程序:Xcode 找不到任何与“maccatalyst.com...”匹配的 Mac Catalyst 应用程序开发配置文件

Mac Catalyst 调整屏幕截图的窗口大小

使用 Crashlytics 构建 Mac Catalyst

如何修复“读写数据沙箱:使用 Mac Catalyst 时出错”