【问题标题】:Keyboard shortcuts with UIKeyCommand in iPadOS 15 betaiPadOS 15 beta 中带有 UIKeyCommand 的键盘快捷键
【发布时间】:2021-10-14 07:10:15
【问题描述】:

由于某种原因,我无法在 iPadOS 15(测试版 5)中使用硬件键盘快捷键。它们适用于大多数键,但不适用于箭头键和 Tab 键。

相同的代码在 Xcode 13(beta 4)中编译并在 iPadOS 14.5 模拟器上运行时似乎运行良好,但在使用相同 Xcode 但在 iPadOS 15 sim 上构建时拒绝运行。我已经在 iPadOS 15 beta 到 5 的实际设备上进行了尝试,结果相同。

这是一个最小的例子:

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        addKeyCommand(UIKeyCommand(title: "UP", action: #selector(handle(key:)), input: UIKeyCommand.inputUpArrow, modifierFlags: []))
        addKeyCommand(UIKeyCommand(title: "DOWN", action: #selector(handle(key:)), input: UIKeyCommand.inputDownArrow, modifierFlags: []))
        addKeyCommand(UIKeyCommand(title: "TAB", action: #selector(handle(key:)), input: "\t", modifierFlags: []))
    }

    @objc func handle(key: UIKeyCommand?) {
        NSLog("Intercepted key: \(key?.title ?? "Unknown")")
    }
}

我没有找到任何相关的报告或公开的雷达,所以我怀疑我可能在这里遗漏了一些东西。如果应该报告这种情况,我应该在哪里报告这样的错误?

谢谢。

【问题讨论】:

    标签: ios ipados ios15 uikeycommand ipados15


    【解决方案1】:

    显然,有一个新的UIKeyCommand 属性wantsPriorityOverSystemBehavior,对于一些 键需要设置为true — 就像我在问题中提到的那样:https://developer.apple.com/documentation/uikit/uikeycommand/3780513-wantspriorityoversystembehavior

    【讨论】:

    • 好答案 ;) 我们也将此解决方案用于箭头键(在 MacCatalyst 应用程序上),但似乎不足以使空格键起作用。有什么线索吗?谢谢!
    • 我可以使用以下代码检测空格键按下。 UIKeyCommand(title: "Space"), action: #selector(handleKey(key:)), input: " ", modifierFlags: []) 希望这会对你有所帮助。
    【解决方案2】:

    解决方案确实是使用wantsPriorityOverSystemBehavior。但是,由于您使用的是 UIResponder 的子类,而不是为已知键添加键命令,因此您可以考虑使用内置方法。它比单独添加每个更有效,而且在模式方面更干净。

    class ViewController: UIViewController {
    
        /// - SeeAlso: UIViewController.viewDidLoad()
        override func viewDidLoad() {
            super.viewDidLoad()
            // do other things, nothing connected with UIKeyCommand
        }
    
        /// - SeeAlso: UIResponder.keyCommands
        override var keyCommands: [UIKeyCommand]? {
            let commands = [
                UIKeyCommand(input: UIKeyCommand.inputUpArrow, modifierFlags: [], action: #selector(actionUp)),
                UIKeyCommand(input: UIKeyCommand.inputDownArrow, modifierFlags: [], action: #selector(actionDown)),
                UIKeyCommand(input: UIKeyCommand.inputLeftArrow, modifierFlags: [], action: #selector(actionLeft)),
                UIKeyCommand(input: UIKeyCommand.inputRightArrow, modifierFlags: [], action: #selector(actionRight))
            ]
            // if your target is iOS 15+ only, you can remove `if` and always apply this rule
            if #available(iOS 15, *) { 
                commands.forEach { $0.wantsPriorityOverSystemBehavior = true }
            }
            return commands
        }
    }
    
    private extension ViewController {
       
        @objc func actionUp() { print("up") }
        @objc func actionDown() { print("down") }
        @objc func actionLeft() { print("left") }
        @objc func actionRight() { print("right") }
    }
    

    很抱歉,这是一个答案,但 cmets 不允许使用漂亮的代码语法 :-) 希望你不介意我的补充,但也许有人不知道 keyCommands 并发现它在这个上下文。至少我提供了一个示例,说明如何使用创建者 @AlexStaravoitau 已经写过的 API 的这个新部分。


    Apple 声称:

    在 iOS 15 之前,系统会将键盘事件传递给您的按键 首先是命令对象,然后是文本输入或焦点系统。如果 您的应用链接到 iOS 14 SDK 或更早版本,您的应用会保留 行为,即使在 iOS 15 或更高版本上运行时也是如此。

    这是一个非常重要的小细节,值得牢记。我误读了它,并认为如果您支持 iOS 14 或更低版本,它将以旧方式工作。但这是我的错误理解,它根本与链接有关(例如,如果您使用 Xcode 12 或更早版本构建并且不在库中添加额外的 iOS)。 因此,即使我的应用仍然支持 iOS 12+,关键命令不再适用于 iOS 15 上 Xcode 13 的新版本。只有在我调整了上述标志后它才开始工作。

    【讨论】:

    • 谢谢!是的,我确实在我的项目中覆盖了keyCommands 属性,我的问题中的示例来自一个测试项目,我一直在疯狂地试图找出问题所在。 ? 非常有趣的与iOS 14 SDK相关的re应用,谢谢分享!
    猜你喜欢
    • 2016-09-18
    • 2014-11-17
    • 1970-01-01
    • 2010-12-04
    • 1970-01-01
    • 1970-01-01
    • 2011-05-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多