Сочетания клавиш с UIKeyCommand в бета-версии iPadOS 15
По какой-то причине я не могу заставить аппаратные сочетания клавиш работать в iPadOS 15 (бета 5). Они работают для большинства клавиш, но не для клавиш со стрелками и клавиши табуляции.
Кажется, что тот же код хорошо работает при компиляции в Xcode 13 (бета 4) и запуске на симуляторе iPadOS 14.5, но затем отказывается работать при сборке с тем же Xcode, но на iPadOS 15 sim. Я пробовал это на реальных устройствах с бета-версиями iPadOS от 15 до 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")")
}
}
Я не нашел никаких связанных отчетов или открытых радаров, поэтому подозреваю, что могу что-то здесь упустить. Если об этом нужно сообщить, где я могу сообщить о подобной ошибке?
Спасибо.
2 ответа
Решение действительно состоит в том, чтобы использовать
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") }
}
Извините, это ответ, но комментарии не позволяют сделать хороший синтаксис кода :-) Надеюсь, вы не возражаете против моего дополнения, но, возможно, кто-то не знает о
Apple утверждает, что:
До iOS 15 система сначала доставляла события клавиатуры в ваши ключевые объекты команд, а затем в системы ввода текста или фокуса. Если ваше приложение ссылается на iOS 14 SDK или более раннюю версию, ваше приложение сохраняет это поведение даже при работе на iOS 15 или более поздней версии.
и это довольно важная маленькая деталь, о которой стоит помнить. Я неправильно прочитал это и подумал, что если вы поддерживаете iOS 14 или ниже, он будет работать по-старому. Но это было мое неправильное понимание, и речь идет о компоновке вообще (например, если вы строите с помощью Xcode 12 или старше и не добавляете дополнительную iOS в библиотеку). Итак, хотя мое приложение по-прежнему поддерживает iOS 12+, ключевые команды больше не работают на новых сборках из Xcode 13 на iOS 15. Оно начало работать только после того, как я адаптировал упомянутый флаг.
Судя по всему, есть новый
UIKeyCommand
свойство
wantsPriorityOverSystemBehavior
, который необходимо установить на
true
для некоторых ключей - например, тех, которые я упомянул в своем вопросе: https://developer.apple.com/documentation/uikit/uikeycommand/3780513-wantspriorityoversystembehavior