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

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

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

Q&A

解決済

1回答

2252閲覧

TabViewにおける画面更新のやり方

ioli

総合スコア12

0グッド

0クリップ

投稿2021/06/21 08:39

###やりたいこと 
TabViewの中にtest1,test2のViewがあります。
test1にはボタンが一つ用意されています。test2には「false」の文字があります。
test1のボタンを押すとtest2で画面更新が行われ文字が「true」に変わる。

###問題点
test1のボタンを押しても、test2での画面更新が行われず、ずっと「false」のままになってしまっています。
プレビューの停止ボタンを押して、再び再生ボタンを押すとtest2の文字は「true」になるため、変数内での値はちゃんと変わっています。
そのため、test1で値が変わった時にtest2の画面の更新がされていないため、それを行うための方法をご教授いただければと思います。

###ContentView

swiftUI

1import SwiftUI 2 3struct ContentView: View { 4 @ObservedObject var user = UserProfile() 5 var body: some View { 6 TabView{ 7 test1View() 8 .tabItem { 9 Image(systemName: "1.circle") 10 } 11 test2View() 12 .tabItem { 13 Image(systemName: "2.circle") 14 } 15 } 16 } 17}

###test1View

SwiftUI

1struct test1View: View { 2 @ObservedObject var user = UserProfile() 3 4 var body: some View { 5 VStack{ 6 Button(action: { 7 user.Toggle() 8 }) { 9 Text("Button1") 10 .font(.title2) 11 .fontWeight(.black) 12 .foregroundColor(Color.white) 13 .padding(.all) 14 .background(user.flag ? Color.gray.opacity(0.2) : Color.gray.opacity(0.7)) 15 } 16 } 17 } 18}

###test2View

SwiftUI

1struct test2View: View { 2 @ObservedObject var user = UserProfile() 3 var body: some View { 4 VStack{ 5 if user.flag { 6 Text("true") 7 } 8 else{ 9 Text("false") 10 } 11 } 12 } 13}

###Store
flagは保存しておきたいのでUserDefaultsを使いました。

Swift

1import Foundation 2 3class UserProfile: ObservableObject { 4 @Published var flag : Bool 5 6 func Toggle(){ 7 flag.toggle() 8 UserDefaults.standard.set(flag, forKey: "flag") 9 } 10 11 init() { 12 flag = UserDefaults.standard.bool(forKey: "flag") 13 } 14}

SwiftUIを最近学習し始めた者のためとても初歩的な質問をしてしまっていると思いますが、どうかよろしくお願いいたいします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

現状だと ContentView, test1View, test2View がそれぞれ別々の UserProfile オブジェクトを持つことになり、そのうちの一つを更新しても他はそのままのため、表示も変わりません。

これを防ぐ方法は、ひとつは ContentView から test1View, test2View それぞれに user を渡してやることです。
参考: 観測可能なモデルデータを作成する (【SwiftUI】アプリケーションのモデルデータを管理する - Qiita)

diff

1 struct ContentView: View { 2 @ObservedObject var user = UserProfile() 3 var body: some View { 4 TabView{ 5- test1View() 6+ test1View(user: user) 7 .tabItem { 8 Image(systemName: "1.circle") 9 } 10- test2View() 11+ test2View(user: user) 12 .tabItem { 13 Image(systemName: "2.circle") 14 }

diff

1 struct test1View: View { 2- @ObservedObject var user = UserProfile() 3+ @ObservedObject var user: UserProfile 4 5 // 略

diff

1 struct test2View: View { 2- @ObservedObject var user = UserProfile() 3+ @ObservedObject var user: UserProfile 4 5 // 略

または、@EnvironmentObject を使う方法もあります。
参考: アプリケーション全体でオブジェクトを共有する (【SwiftUI】アプリケーションのモデルデータを管理する - Qiita)

diff

1 @main 2 struct XXXApp: App { 3+ @ObservedObject var user = UserProfile() 4 5 var body: some Scene { 6 WindowGroup { 7 ContentView() 8+ .environmentObject(user) 9 } 10 } 11 }

diff

1 struct ContentView: View { 2- @ObservedObject var user = UserProfile() 3 4 // 略

diff

1 struct test1View: View { 2- @ObservedObject var user = UserProfile() 3+ @EnvironmentObject var user: UserProfile 4 5 // 略

diff

1 struct test2View: View { 2- @ObservedObject var user = UserProfile() 3+ @EnvironmentObject var user: UserProfile 4 5 // 略

ちなみに、型名 test1View, test2View ですが、Swift ではクラスや構造体などの型名の先頭の文字は大文字にする (つまり、Test1View, Test2View とする) のが一般的です。

投稿2021/06/21 09:38

hoshi-takanori

総合スコア7901

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

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

ioli

2021/06/21 11:17

やりたいことを実装することができました。本当にありがとうございます! ちなみにObservedObjectとEnvironmentObjectを比べてみると、ObservedObjectは他のviewに受け渡しをしなければならないのに対してEnvironmentObjectは受け渡しをしなくても済むということで、圧倒的にEnvironmentObjectの方が便利ではないかなと思ったのですが、ObservedObjectの方にもメリットはあったりするのですか? 重ねての質問失礼致します。
hoshi-takanori

2021/06/22 00:35

EnvironmentObject だと、たぶん同じ型の値を複数切り換えて使うということができなくなると思います。 例えば、ユーザーのリストを表示して、タップしたらそのユーザーの情報を表示・更新するような場合は、選択されたユーザーの情報を ObservedObject で受け渡すことになるのでは。
ioli

2021/06/22 06:57

そういった使い分けをする必要があるんですね! 理解が進みました!ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問