swiftui - タブビューで共通変数を使用するにはどうすればよいですか?

okwaves2024-01-25  9

現在、SwiftUI を使用してアプリケーションを開発しています。

このアプリには 3 つの構造体があります

①コンテンツビュー ②ファーストビュー ③セカンドビュー

これら 3 つの構造体は、タブ ビューでのページ遷移を行います。

このアプリには、ObservableObject アノテーションを使用した Bool の共通変数型があります。

FirstViewとSecondViewのテキストビューを変数の条件によって表示・非表示に変更したいのですが、FirstViewでは思ったようにビューが変更されません...

この状況を解決するにはどうすればよいですか?

コードは次のとおりです。

ContentView.swift

import SwiftUI

struct ContentView: View {
    var body: some View {
        TabView {
            FirstView()
                .tabItem {
                    Text("First")
            }.tag(1)

            SecondView()
                .tabItem {
                    Text("Second")
            }.tag(2)
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

FirstView.swift

import SwiftUI

struct FirstView: View {

    @ObservedObject var firstCheck: ViewModel = ViewModel() 

    var body: some View {
        VStack{
            if firstCheck.check == true{
                    Text("checked")
            }
        }
    }
}

struct FirstView_Previews: PreviewProvider {
    static var previews: some View {
        FirstView()
    }
}

SecondView.swift

import SwiftUI

struct SecondView: View {

    @ObservedObject var secondCheck = ViewModel()


    var body: some View {
        VStack{
            Toggle(
                isOn: $secondCheck.check
            ){
                Text("change")
            }
            if self.secondCheck.check == true{
                Text("checked")
            }
        }
    }
}

struct SecondView_Previews: PreviewProvider {
    static var previews: some View {
        SecondView()
    }
}

ViewModel.swift

import Foundation

final class ViewModel: ObservableObject {
    @Published var check: Bool = false
}

Xcode: バージョン 11.7



------------------------

オブジェクトを 1 か所に保持し、親ビューにすることができます

struct ContentView: View {
    @ObservedObject var viewModel = ViewModel()
//    @StateObject var viewModel = ViewModel()     // SwiftUI 2.0


    var body: some View {
        TabView {
           // .. other code here
        }
        .environmentObject(viewModel)   // << inject here
    }
}

その後、両方のビューで次のように使用します (2 番目は同じ)

struct FirstView: View {

    @EnvironmentObject var firstCheck: ViewModel   // declare only
                                                   // will be injected by type

    var body: some View {
        VStack{
            if firstCheck.check == true{
                    Text("checked")
            }
        }
    }
}

1

ご協力ありがとうございます。コードは期待どおりに機能するようになりました。

– ティオ

2020 年 9 月 3 日 12:11

総合生活情報サイト - OKWAVES
総合生活情報サイト - OKWAVES
生活総合情報サイトokwaves(オールアバウト)。その道のプロ(専門家)が、日常生活をより豊かに快適にするノウハウから業界の最新動向、読み物コラムまで、多彩なコンテンツを発信。