iOS: メンション入力/表示の実装手法(3)

p0dee
May 9, 2021

前回の続き。今回は、

  • カーソル操作/削除操作いずれも1文字扱いとする
    → メンション表示にNSTextAttachmentを使用

について。

といってもやることは簡単で、メンション表示全体をUIImageとして、それをNSTextAttachment.imageに設定し、NSAttributedStringに挿入するだけ。

上記実装の結果

これを、正規表現により抽出した該当箇所に差し替えたり、メッセージ入力中はメンション先の選択時に、カーソル位置に挿入したりすればよい。

NSTextAttachmentとして挿入することにより、おのずと1文字扱いされるため、以下のようなメリットがある。

  • デリート操作1発でメンション表示を削除できる
  • メンション表示の内部にカーソルが入り得ないため、考慮すべきユースケースを減らせる(メンション表示内部で文字入力が行われた、削除操作が行われた、などの考慮)
  • attachmentのサイズに従い、UILabelUITextViewにより改行処理が自動的に行われる

上で「メッセージ入力中でのメンション先選択操作」に言及したが、さらっと過ぎるので具体的に触れてみる。これは、よくある以下の選択表示/操作のこと。

今回、これを表示/非表示する条件として、以下を採用した。

  • メッセージフィールドに「@」が入力されたらメンション先選択を表示
  • これを表示中に、つづけて何かの入力があれば、メンション先選択表示を破棄
  • メンション先が選択されたら、表示を破棄
「@」入力に応じたメンション先選択の表示/非表示

メッセージ入力中に、上述の操作によってメンション先が選択された際、メッセージフィールドにメンション表示(NSTextAttachment)を挿入するのだが、単純そうに見えてこれにはいくつか落とし穴があった。

まず、一連の操作のトリガーとなった「@」が存在するはずなので、これを削除することを忘れないようにする。そうでないと、@@花子のようになってしまう。

//カーソル直前の文字(@であるはず)を消すtextView.deleteBackward()

次に、挿入位置の特定。常に文字列末尾にappendするだけなら難はない。しかし現実はそう甘くはない。ユーザーが途中で思い立って、カーソル位置を動かす場合を考慮する必要がある。

ユーザーは自由にカーソルを動かして挿入位置を決めることができる

textView上のカーソル位置を特定したり変更したりするのが、思いのほか面倒だった。

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

No responses yet

Write a response