🐰
AppKitで左右カーソルキーでフォーカスリングを移動する
macOS AppKitのコントロールはキーボードナビゲーションに対応しており、フォーカスが当たると周囲にフォーカスリングが描画される仕組みになっています。キーボードナビゲーションはTabで次のキービューに移動、Shift Tabで前のキービューに移動させることができます。この操作を別のキーの組み合わせ、例えば左右カーソルキーでも操作できるようにしてみようと思います。
フォーカスリング
フォーカスリングを表示してキーボードナビゲーションを使えるようにするには、システム設定でキーボードナビゲーションを有効にする必要があります。
対応させたいビュークラスにてkeyDown()
をオーバーライドし、ウインドウに対して次のメソッドを呼び出します。
左右カーソルキーはNSEvent.specialKeyで判定します。
class MyView: NSView {
override func keyDown(with event: NSEvent) {
if event.isLeftArrow {
// ←(左カーソルキー)で前のキービューにフォーカスを移す; shift tab と同等効果
window?.selectPreviousKeyView(event) // senderはnilでもいいかも
return
}
if event.isRightArrow {
// →(右カーソルキー)で次のキービューにフォーカスを移す; tab と同等効果
window?.selectNextKeyView(event)
return
}
super.keyDown(with: event)
}
}
extension NSEvent {
/// ←判定
var isLeftArrow: Bool {
specialKey == .leftArrow
}
/// →判定
var isRightArrow: Bool {
specialKey == .rightArrow
}
}
キービュー(key view)とは、キーボード等のイベントを受け取ることができるビューです。キービューがfirst responderになるとそのビューに対してキーボードイベントを送ることができるようになります。キーボードナビゲーション(フォーカスリングの移動)はキービュー間で行われます。
キービューでもisHidden == true
で隠れている場合はフォーカスが当たらず、イベントも届きません。
キービュー状態やキーボードイベントの制御を行うには、canBecomeKeyView
やacceptsFirstResponder
プロパティをオーバーライドして対応します。
関連:
Discussion