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

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

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

Q&A

解決済

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

DeepSea
DeepSea

総合スコア4

1回答

0グッド

0クリップ

165閲覧

投稿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)

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

回答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

総合スコア6210

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

DeepSea

2022/12/08 04:14

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

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

ただいまの回答率
86.02%

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

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

質問する

関連した質問

同じタグがついた質問を見る