Shift + EnterでUITextViewを改行
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:)))]
}
UITextViewDelegate
のtextView(_:shouldChangeTextIn:replacementString:)
を実装している場合であっても、このkeyCommands
の実装がインターセプトするため、テキスト入力まで辿り着かずデリゲートメソッドは呼ばれません。
なので、任意の文字列を追加した後にデリゲートが動いて欲しいときは、手動で呼んであげるようにすると良いでしょう。
ポイント2: アクションの実装
UITextView
のtext
プロパティに直接\n
を代入したいところですが、firstResponder
が外れてしまう上に予期しない挙動を引き起こしてしまいます。
そのため、現在アクティブなUITextView/UITextField
のテキストに変更を加える場合は、UIKeyInput
プロトコルに属しているinsertText(_:)メソッドを利用しましょう。
このメソッドは、テキストの現在カーソルが当たっているindexに対してStringの挿入をして、その後テキストを表示し直してくれます。(バッキングストアなどについて気になる場合は、TextKitをご参照ください)
@objc func newLine(sender: UIKeyCommand) {
// プログラム経由のテキスト更新はデリゲートメソッドは呼ばれない
insertText("\n")
}
プログラム経由でテキスト更新をした場合にはデリゲートメソッドは呼ばれないことに注意してください。
まとめ
以上のような2つのポイントを抑えて実装することで、Shift + Enter
での改行操作が実現可能となります。
もしもっとスマートな実装方法などご存知の場合は、ご教授頂けると助かります。
Author And Source
この問題について(Shift + EnterでUITextViewを改行), 我々は、より多くの情報をここで見つけました https://qiita.com/yosshi4486/items/01b94ee68f82e8e2bf89著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .