Open1
SwiftUI: モデルをアップデートしてるのにビューが更新されない
モデルをアップデートしているのにビューが更新されない、というのでハマって結構時間を食ったのでメモしておきます。
現象としては、以下のようになります。
- ビュー側で
@ObservedObject
で監視しているモデルデータがある - モデルデータは当然
@ObservableObject
のclass
で、監視したい値は@Published
になっている - モデル側で値を変えて、変えたタイミングでその値を
print
する - ビュー側では
var body
の先頭でlet _ = print
で、再描画される値をprint
する - 値を変える→ビューの再描画は、実際にこの順で実行されている。
print
の順がそうなっている - 値を変えたときに
print
される値と、ビューの再描画でprint
される値が違う。ビューの再描画では変更前の値がprint
される
最初は、バックグラウンドから@Published
の値を変えていて、紫の警告が出たんでそれが原因かなと思っていたんですが、それを直しても更新されない。
で、何か違うものを見ているんじゃないだろうかということで、class
にUUIDを追加して同時にprint
するようにしたら、変更したときのUUIDと、再描画されるUUIDが違うんですね。
何のことはない、最上位のビューで@EnvironmentObject
に定義して、さらに内側のビューで@StateObject
を定義してってやってしまっていました。そのせいで、別々のオブジェクトを更新・参照していた、という話でした。
App本体に実装する前に軽いプロトを作って動作確認した上で取り込もう、と思ってたんですが、とんだ落とし穴でした。