0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Shift + EnterでUITextViewを改行

Last updated at Posted at 2020-10-23

SmartKeyboardなども発売され、iPadにはずっとキーボードを接続して利用している。というユーザーも多いのではないかと思いますが、そのような市場の様子を見て「enterを確定や直下の新規作成操作とし、shift + enterで改行操作」と思った場合、素直に対応したAPIがあれば良いですがUITextViewDelegateには該当するものが存在しないため、少し工夫をする必要があります。

この記事ではその実現方法について解説します。

方針

こちらのStackoverflowの質問が参考にしましたが、

**「UIKeyCommandをoverrideしてインターセプトし、shift + enterで独自の改行アクションを実行する」**という方針になります。

実装

コードはこちらのgistに投稿しましたので参考にしてください。

今回はUITextViewのサブクラスを利用して実現を図りました。

ポイント1: keyCommandsのoverride

システム定義以外のあるキーが押されたとき、システムはresponderChainを探して該当するキーに対応するUIKeyCommandが実装されているか確認し、存在すればそのアクションを実行します。

以下の実装では、shift + return(enter)を受け取るとnewLine(sender:)というアクションを実行するようなコマンドを返しています。

override var keyCommands: [UIKeyCommand]? {
// キーボードへのinputは、returnなので"\r". うっかり"\n"としてしまう事があるが、それは押下したキーではないため.
        return [UIKeyCommand(input: "\r", modifierFlags: .shift, action: #selector(newLine(sender:)))]
 }

UITextViewDelegatetextView(_:shouldChangeTextIn:replacementString:)を実装している場合であっても、このkeyCommandsの実装がインターセプトするため、テキスト入力まで辿り着かずデリゲートメソッドは呼ばれません。

なので、任意の文字列を追加した後にデリゲートが動いて欲しいときは、手動で呼んであげるようにすると良いでしょう。

ポイント2: アクションの実装

UITextViewtextプロパティに直接\nを代入したいところですが、firstResponderが外れてしまう上に予期しない挙動を引き起こしてしまいます。

そのため、現在アクティブなUITextView/UITextFieldのテキストに変更を加える場合は、UIKeyInputプロトコルに属しているinsertText(_:)メソッドを利用しましょう。

このメソッドは、テキストの現在カーソルが当たっているindexに対してStringの挿入をして、その後テキストを表示し直してくれます。(バッキングストアなどについて気になる場合は、TextKitをご参照ください)

@objc func newLine(sender: UIKeyCommand) {
    // プログラム経由のテキスト更新はデリゲートメソッドは呼ばれない
    insertText("\n")
}

プログラム経由でテキスト更新をした場合にはデリゲートメソッドは呼ばれないことに注意してください。

まとめ

以上のような2つのポイントを抑えて実装することで、Shift + Enterでの改行操作が実現可能となります。

もしもっとスマートな実装方法などご存知の場合は、ご教授頂けると助かります。

0
1
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?