質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%

Q&A

解決済

1回答

1116閲覧

[SwiftUI] TextFieldに入力終了後、値が戻ってしまう

DeepSea

総合スコア4

0グッド

0クリップ

投稿2022/12/07 21:33

編集2022/12/07 21:34

問題の概要

次のデータ構造に対し、TextFieldで編集を行う画面を実装しています。
・StaticなObservableObjectクラスStaticModelにvalue変数を定義する
・ViewModelクラスViewModelStaticModel.valueをBindingする
・TextFieldでViewModel.valueをBindingする

アプリは次の動作となりました。
・TextFieldの入力は正しく完了し、StaticModel.valueの値が変化する
・TextFieldからフォーカスが移動すると、TextFieldの表示が戻る
→初期表示時「0」が表示されている場合、「50」を入力した後にフォーカスを外すと「0」表示に戻る
→「0」表示に戻った時点で、StaticModel.valueの値は「50」
・再度TextFieldにフォーカスを移したタイミングで表示が正しくなる

実現したいこと

上記のデータ構造でTextFieldからフォーカスを外した際に値が戻らないようにする方法をご教示いただけますと幸いです。

該当のソースコード

StaticModel

1class StaticModel: ObservableObject { 2 3 static let shared = StaticModel() 4 5 @Published var value = 0 { 6 didSet { 7 print("value = \(value)") 8 } 9 } 10}

ViewModel

1class ViewModel: ObservableObject { 2 3 @Binding var value: Int 4 5 init(value: Binding<Int>) { 6 _value = value 7 } 8}

ContentView

1struct ContentView: View { 2 3 @StateObject var viewModel: ViewModel 4 5 var body: some View { 6 Form { 7 Section { 8 HStack { 9 Text("数値") 10 TextField("数値を入力してください", value: $viewModel.value, formatter: NumberFormatter()) 11 .multilineTextAlignment(.trailing) 12 } 13 } 14 } 15 } 16}

App

1@main 2struct SampleApp: App { 3 4 @StateObject var staticModel = StaticModel.shared 5 6 var body: some Scene { 7 WindowGroup { 8 ContentView(viewModel: ViewModel(value: $staticModel.value)) 9 } 10 } 11}

試したこと

value変数をViewModelに持たせる等単純な実装に変えた場合、TextFieldの動作は正しくなりました。
StaticModelvalue変数を持たせる事が原因となっていると考えておりますが、解決策が見いだせていません。

補足情報(FW/ツールのバージョンなど)

Xcode Version 14.1 (14B47b)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ネストされたObservableObjectの変更はViewで検知されないので、うまく動作しません。

https://stackoverflow.com/questions/58406287/how-to-tell-swiftui-views-to-bind-to-nested-observableobjects

のSorin Licaの回答のように、objectWillChangeを使ってネストされたObservableObjectの変更を検知して自身の変更として伝えればうまくいくようですが、ahezeの回答にある通り、構造をよく見直すべきように思います。StaticModelがシングルトンモデルなのであれば、ViewModelの中に保持して参照するのではなく、アプリ全体で共通に参照/更新するモデルとして、@EnvironmentObjectでstaticModelを宣言するのがよさそうにも思います。

投稿2022/12/08 02:57

TakeOne

総合スコア6299

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

DeepSea

2022/12/08 04:14

詳細にご回答いただき、ありがとうございます。 SwiftUIの仕様なのですね。 納得できました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問