1
votes

I'm currently developing an application using SwiftUI.

This app has 3 structs

  • ①ContentView
  • ②FirstView
  • ③SecondView

These 3 structs do page transition in Tab View.

And this app has a common variable type of Bool using ObservableObject annotation.


I want to change to appear and disappear Text View in the FirstView and the SecondView depends on the condition of the variable, but the FirstView doesn't change a view as I expected...

How can I solve this situation?


Here are the codes:

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: Version 11.7

1

1 Answers

1
votes

Keep object in one place, can be parent view

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
    }
}

and then use in both views like (for second the same)

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")
            }
        }
    }
}