SwiftUI iOS - как перехватить события аппаратного ключа - PullRequest
4 голосов
/ 18 января 2020

Я новичок в iOS разработке. После обучения я создал простой калькулятор с помощью SwiftUI.

У меня есть клавиатура, подключенная к iPad, и я хотел бы иметь возможность вводить значения с помощью клавиатуры.

Как я могу захватывать и обрабатывать события аппаратной клавиатуры в приложении SwiftUI (без текстового поля)? Я попытался использовать ключевые команды на SceneDelegate (UIResponder), как показано здесь, но это не работает для меня. Как только я нажимаю любую клавишу на своем iPad, в представлении трассировки XCode появляется «Соединение с деамоном было недействительным».

 class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var window: UIWindow?

    override var canBecomeFirstResponder: Bool {
        return true;
    }
    override var keyCommands: [UIKeyCommand]? {
        return [
            UIKeyCommand(input: "a", modifierFlags: [], action: #selector(test)),
            UIKeyCommand(input: UIKeyCommand.inputLeftArrow, modifierFlags: [], action: #selector(test))
        ]
    }

    @objc func test(_ sender: UIKeyCommand) {
        print("test was pressed")
    }

Спасибо

1 Ответ

5 голосов
/ 18 января 2020

Необходимо переопределить контроллер вида хостинга, и все работает. Протестировано с Xcode 11.2 / iOS 13.2

Вот пример кода

class KeyTestController<Content>: UIHostingController<Content> where Content: View {

    override func becomeFirstResponder() -> Bool {
        true
    }

    override var keyCommands: [UIKeyCommand]? {
        return [
            UIKeyCommand(input: "1", modifierFlags: [], action: #selector(test)),
            UIKeyCommand(input: "0", modifierFlags: [], action: #selector(test)),
            UIKeyCommand(input: UIKeyCommand.inputLeftArrow, modifierFlags: [], action: #selector(test))
        ]
    }

    @objc func test(_ sender: UIKeyCommand) {
        print(">>> test was pressed")
    }

}

и где-то в SceneDelegate ниже

window.rootViewController = KeyTestController(rootView: contentView)
...