SwiftUIのTextFieldに入力した1文字目が変換対象にならない問題とその対処法
SwiftUIのTextFieldに日本語入力キーボードで文字を入力すると、1 文字目が変換対象にならないことがあります。
例えば、キーボードで「a」「u」と入力すると、1文字目の「あ」が変換対象にならない場合があります。(sheet (opens in a new tab)の上などにTextFieldを配置すると、高確率で発生)
この現象はUIKitのUITextFieldでは発生しないので、SwiftUIのバグです。
対処法: UITextFieldをラップした TextField2
を作る
TextField2.swift
問題解決の鍵となるのが以下の部分で、変換候補がない場合(markedTextRange (opens in a new tab) == nil)のみUITextFieldのtextをセットするようにしています。
// NOTE: @Bindingの値が変更された時、updateUIViewが呼び出される
func updateUIView(_ uiView: UITextField, context: Context) {
// NOTE: 変換候補がない場合(markedTextRange == nil)のみtextをセットする.
// この条件がないと、ユーザが入力した1文字目が変換対象にならないことがある.
if uiView.text != text && uiView.markedTextRange == nil {
uiView.text = text
}
}
このTextView2で出来ること・出来ないことは以下の通りです。
TextView2で出来ること
- title(プレースホルダー)の指定
- onEditingChangedイベントの受信
- onCommitイベントの受信
- キーボードのToolbarにCancelボタンを表示(modifierで
onCancel
を指定した時のみ表示されます) - keyboardType (opens in a new tab)の指定
- clearButtonMode (opens in a new tab)の指定
TextView2で出来ないこと
- 複数行入力
- SwiftUIのTextFieldは
axis: .vertical
を指定することで複数行の入力が可能ですが、TextField2は複数行に対応していません。 - 元になっているUITextFieldが複数行に対応していないためです。
- 試していませんが、UITextViewをラップすれば複数行に対応できるかもしれません。
- SwiftUIのTextFieldは
使用例
比較のためSwiftUIのTextField と TextField2 を上下に並べてみました。
ContentView.swift
Github
https://github.com/k-yamada/SwiftUITextFieldSample (opens in a new tab)
© 品川アプリ.RSS