[Swift] iPadOS用アプリにキーボードショートカットを追加する
iPadOSではキーボードやポインティングデバイス(マウスやトラックパッドなど)がサポートされています。キーボードサポートでは入力のためだけでなく、アプリごとのキーボードショートカットもサポートされています。今回はそんなiPadOS用アプリへのキーボードショートカットの実装について。
まずはサンプルコード
キーボードショートカットは UIKit の UIResponder が提供している keyCommands プロパティをオーバーライドしてあげることで追加できます。UIResponder のプロパティなのでちょっとしたアプリの場合は ViewController とかに直接仕込んじゃってもいいんじゃないっすかね。
以下のサンプルコードでは Emacs のキーバインドのように Ctrl+Y でクリップボードからのペーストをできるようにします。
override var keyCommands: [UIKeyCommand]? {
return [
.init(title: "ペースト", action: #selector(paste(_:)), input: "y", modifierFlags: [.control]),
]
}
ひとつずつ見ていきましょう。
keyCommands
まず今回オーバーライドする keyCommands
プロパティの戻り値は UIKeyCommand の配列です。なので複数のキーボードショートカットを定義したい時は便宜戻り値として返す配列に UIKeyCommand のイニシャライザである .init()
で初期化済みのインスタンスそれぞれ追加してあげればOKです。ただし UIKeyCommand 自体は引数なしでも初期化できますが、上のコードを踏襲する場合は引数なしでイニシャライザを呼んでしまうと意味がわからなくなるので注意。
UIKeyCommand のプロパティ
次に戻り値の配列の要素となる UIKeyCommand のイニシャライザの引数を見ていきましょう。それぞれの引数は当該の UIKeyCommand のインスタンスのプロパティとしてもアクセスできます。
title
title
に渡した文字列はキーボードのコマンドキーを長押しした時のメニュー項目名に表示されます。正直、それ以上でもそれ以下でもないのですが実際にはアプリのローカライズを考えて指定した方がいいでしょう。
action
action
に渡した selector には実際に呼び出されるメソッドを指定します。今回はUIResponderStandardEditActions 組み込みの paste メソッドを呼んでいますが、独自のメソッドを呼ぶ場合はそのメソッドの定義で @objc
の指定が必須です。以下のコードみたいな感じ。
@objc func pasteFromClipboard () {
}
先日別の記事でも @objc
ってなっているサンプルのコードが出てきていたけど、社内の誰かこの辺のちゃんとした解説記事書いてくれないかな?
input / modifierFlags
input
に渡した値は modifierFlags
で渡したキーとのコンビネーションでそれそのままショートカットキーとなります。modifierFlags
自体はUIKeyModifierFlagsなので指定できるオプションはリファレンスを参照してみてください。とりあえずショートカットキーとしてよく使いそうなのは.command
とか.control
かな。
これで最低限、iPadOS用アプリにキーボードショートカットを追加することができます。ちなみに今回の記事では UIKeyCommand に関して必要最低限しか書いていないので、便宜公式のドキュメントを読んでみてください。
Cmd+W の上書きもできちゃった
ちなみに冒頭のスクリーンショットでコピーとして Cmd+W のキーボードショートカットが表示されているんですけど、実はこのキーボードショートカットって iPadOS だとデフォルトでは作業中のアプリを閉じるキーボードショートカットなんですよね。これも明示的に今回の方法を応用してキーボードショートカットとして定義してあげると、Cmd+W でアプリを閉じることをキャンセルして他の機能を割り当てることもできちゃったりしました。