SwiftUI の TextField バインディングで didSet が 2 回呼び出されるのはなぜですか? 質問する

SwiftUI の TextField バインディングで didSet が 2 回呼び出されるのはなぜですか? 質問する

次のようなものだけを表示する非常に基本的なビューがありますTextField:

ビュー

struct ContentView: View {

    @StateObject var viewModel = ViewModel()
    
    var body: some View {
        TextField("Enter a string...", text: $viewModel.string)
    }
    
}

TextFieldのテキストはビュー モデルのプロパティにバインドされますstring

ビューモデル

class ViewModel: ObservableObject {
    
    @Published var string: String = "" {
        didSet {
            print("didSet string:", string)
        }
    }
    
}

文字列が変更されるたびにカスタム アクションを実行するプロパティ オブザーバーを追加しましたdidSet。この単純な例では、コンソールに文字列を出力するだけです。

観察

このコードを実行し、テキスト フィールドに文字列「123」を入力すると、次のような出力が得られます。

didSet string: 1
didSet string: 1
didSet string: 12
didSet string: 12
didSet string: 123
didSet string: 123

質問:

なぜですか?入力する文字ごとにクロージャが 2 回呼び出される
のはなぜですかdidSet? (文字ごとに 1 回呼び出されることを期待しています。)

コードに何か問題があるのでしょうか、それともこれは想定された動作なのでしょうか?

ベストアンサー1

Xcode 14.2 RC と iOS 16.2 RC でこの問題が見られますが、奇妙なことに、 または を追加すると修正され.textFieldStyle(.plain)ます.textFieldStyle(.roundedBorder)

textFieldStyle がないとなぜこれに影響するのかはよくわかりませんが、バインディング呼び出しセットは次のようになります:{}2回textFieldStyle が設定されていない場合、textFieldStyle のいずれかを追加すると、通常どおり動作し、set:{} が 1 回だけ呼び出されます。

これが誰かの役に立つことを願います!

おすすめ記事