LoginSignup
6
8

More than 5 years have passed since last update.

iOSでキーボードショートカットに対応する

Last updated at Posted at 2018-11-11

やりたいこと

iPad Pro 11インチとキーボードフォリオとApple Pencilを購入して、色々なアプリをキーボードで操作できることに気がつきました(遅い?)。やっぱりできるアプリはキーボードショートカットが充実しています。macOSでの経験則がそのまま活かせる訳で、どうやっているのかなと調べてみました。

仕組み

以下のUIResponderのkeyCommandsをオーバーライドします。

@interface UIResponder (UIResponderKeyCommands)
@property (nullable,nonatomic,readonly) NSArray<UIKeyCommand *> *keyCommands NS_AVAILABLE_IOS(7_0); // returns an array of UIKeyCommand objects<
@end

適当なViewControllerを用意してショートカットを登録します。

override var keyCommands: [UIKeyCommand]? {
    let commands = [
        // コマンド+Oが押された時の定義
        UIKeyCommand(input: "O", modifierFlags: .command, action: #selector(handleShortcutCommand(command:)), discoverabilityTitle: "開く")
    ]

    return commands
}

@objc func handleShortcutCommand(command: UIKeyCommand) {
    if command.input == "O" {
        print("開くコマンド実行")
    }
}

ビルドしてコマンド+Oを実行するとログに開くコマンド実行と表示されました。コマンドキーを長押しすることで操作可能なショートカット一覧が表示されます。定義した開くコマンドが表示されるはずです。

要は各ViewControllerにこれらを仕込んであげることでキーボード操作が実現できます。便利便利。

もう一歩踏み込んで

例えば、あるビューからモーダルで別のビューに遷移するアプリを考えてみましょう。最初のビューからコマンド+Oでモーダルを開き、モーダルはコマンド+Wで閉じたいです。

それぞれのViewControllerに開くコマンドと閉じるコマンドを定義すれば良さそうですが、実際にやってみると、モーダル表示中にコマンドキーを長押しすると開く閉じるが二つ出てきてしまいます。

これを回避するために、以下のようにモーダルが表示されている時はkeyCommandsでnilを返してやりましょう。

override var keyCommands: [UIKeyCommand]? {
    // モーダルが表示されてたらnilを返す
    if self.presentedViewController != nil {
        return nil
    }

    let commands = [
        // コマンド+Oが押された時の定義
        UIKeyCommand(input: "O", modifierFlags: .command, action: #selector(handleShortcutCommand(command:)), discoverabilityTitle: "開く")
    ]

    return commands
}

@objc func handleShortcutCommand(command: UIKeyCommand) {
    if command.input == "O" {
        print("開くコマンド")
    }
}
6
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
8