LoginSignup
5
1

More than 5 years have passed since last update.

IMEを使う(iOS編)

Posted at

はじめに

これまでは主にデスクトップ向けのIMEを扱ってきましたが、本日はモバイル向けのOSであるiOSのIME APIについてです。
(UWPは例外的にモバイルも含むプラットフォームでしたが)

モバイルでも日本語入力という枷からは逃れることはできないので、iOSにもIME APIが用意されています。
とはいえ、サードパーティのIME自体は比較的最近(iOS 8)までは存在しませんでしたね。

UITextInput

iOSのIME APIの中心となるのがUITextInputなのは間違い無いのですが、その実装はひどく面倒なものになっています。
UITextInputUIKeyInputを、UIKeyInputUITextInputTraitsを、UITextInputTraitsNSObjectProtocolを継承しています。

  1. UIView, UITextInputを継承したViewを作る
    • becomeFirstResponder()
    • canBecomeFirstResponder: Bool = true
  2. 基本実装: macOS編NSTextInputClientと同様の実装をこちらでも行う
  3. UITextPositionを継承したテキストの位置を保持するクラスを作る
  4. TextRangeを継承したテキストの範囲を保持するクラスを作る
  5. 3.と4.で作ったクラスのインスタンス同士の比較関数を作る
    • UITextPosition同士を比較したり、UITextPositionTextRangeに含まれるかを返したりする関数
    • (この辺はWindowsのIAnchorに近いものがある)
  6. 音声入力周りの実装がある
    • 音声入力中のPlaceholderを作って返す
    • Placeholderのディスプレイ上の位置を返す
    • 不要になったPlaceholderを削除する
    • 結果を挿入する

おわりに

iOSのIME APIは基本実装自体はmacOSとほとんど変わらないのですが、とにかく周辺実装がたくさん増えてて大変という感じです。
一番大変そうなのがvar tokenizer: UITextInputTokenizerの実装ですね。
テキストの切れ目などをいい感じに返すやつです。
(多分サードパーティのキーボードとかで文節単位で移動できたりするのはここを叩いてるのかな)

縦書きに関するメモ

縦書きに関連するのはfunc selectionRects(for range: UITextRange) -> [Any]で返すUITextSelectionRectisVertical: Boolがある程度です。
来年にはiOS版のTATEditorも作るので、そのときに何かわかるかなあと祈ってます。
(標準のキーボードだと活用されてなさそうな気が……?)

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