Search code examples
swiftswiftuiobservedobject

How to change a boolean instance of a class in another view?


I want to tap a button in one view and change the text on another view. The button that changes the bool is on LessonOne and the text I want to show in on my ContentView.

The code in my Lesson One is:

import SwiftUI
import Combine

class LessonTwoButton: ObservableObject {
    let didChange = PassthroughSubject <Void, Never >()
    var ButtonIsTapped = false {didSet {didChange.send()}}
}

struct LessonOne: View {
    
    @ObservedObject var ActivateNextLesson = LessonTwoButton ()
    
    var body: some View {
        
        VStack{
            Button (action: {
                self.ActivateNextLesson.ButtonIsTapped.toggle()
            }
            , label: {
                Text("Activate the next lesson")
            })
            
        }
        
    }
    
}

The code in my ContentView is:

import SwiftUI
import Combine

struct ContentView: View {
    
    @ObservedObject var lessontwobutton = LessonTwoButton()
    
    var body: some View {
        NavigationView{
            
            VStack{
                Text("Hello, world!")
                    .padding()
                
                if lessontwobutton.ButtonIsTapped{
                    Text ("The button has been pressed. Your lesson is unlocked")}
                else{
                    Text("This lesson is locked")
                }
                
                NavigationLink (
                    destination: LessonOne(),
                    label: {
                        Text("Next view")
                    })
                
            }
            
        }
        
    }
}

The code runs, but it just doesn’t bind… I go on LessonOne, tap the button, get back to ContentView and nothing is changed. Can you please tell me what to do?


Solution

  • You need to use the same LessonTwoButton instance in both views:

    struct ContentView: View {
        @ObservedObject var lessontwobutton = LessonTwoButton() // create in parent only
        ...
    
    struct LessonOne: View {
        @ObservedObject var ActivateNextLesson: LessonTwoButton // declare only
        ...
    }
    
    NavigationLink(
        destination: LessonOne(ActivateNextLesson: lessontwobutton), // pass here
        label: {
            Text("Next view")
        }
    )
    

    And LessonTwoButton can be simplified:

    class LessonTwoButton: ObservableObject {
        @Published var ButtonIsTapped = false
    }