SwiftUIのTextFieldに入力した1文字目が変換対象にならない問題とその対処法

kyamada,SwiftUITextFieldUITextField

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で出来ること

TextView2で出来ないこと

使用例

比較のためSwiftUIのTextField と TextField2 を上下に並べてみました。

ContentView.swift

Github

https://github.com/k-yamada/SwiftUITextFieldSample (opens in a new tab)

© 品川アプリ.RSS