SwiftUI how to access ContentView variables from another class

Viewed 1552

I'm new to SwiftUI. Trying to advance my Timer app, I got stuck.

In my ContentView, I have two ObservedObjects, the Timer object which manages the timer functionality and the Settings object, which stores all user settings. My goal is that if the user changes the toggle setting, a variable gets set in the instance of MyTimer which is defined in the ContentView class.

My problem is that I don't know how to access that instance from the class Settings.

It's probably a very easy solution, however, I'm trying to get this working for quite some time now and I was out of luck.

Thanks for helping!


struct ContentView: View {

    @ObservedObject var myTimer = MyTimer()
    @ObservedObject var settings = Settings()

...

 Toggle(isOn: self.$settings.muteInSilenceMode) {
        Text("Mute sound in silence mode")
                                    }
...

}

class Settings: ObservableObject {

...

    @Published var muteInSilenceMode: Bool = UserDefaults.standard.bool(forKey: "muteInSilenceMode"){
              didSet{
                  UserDefaults.standard.set(self.muteInSilenceMode, forKey: "muteInSilenceMode"

                  // I want to access the Timer object from here

              }
          }
...

}

2 Answers

I do not see what your Settings() has to do with your question but I think an answer for your question looks like this:

struct ContentView : View {

    @ObservedObject var myTimer = MyTimer()
    @ObservedObject var settings = Settings()

    @State private var timer: Bool

    var body: some View {

        let toggleTimer = Binding<Bool> (
            get: { self.timer},
            set: { newValue in
                self.timer = newValue
                if self.timer {
                    myTimer.theVaribableYouWantToChange = true // Didn't know the name of your variable.
                } else {
                    // Whatever shall happen if the Toggle gets deactivated.
                }
        })

        return HStack {
            Toggle(isOn: toggleTimer) {Text("Activate") }
        }
    }
}

Here is possible alternate, just simpler (also you can attach .onReceive to any other internal view).

struct ContentView: View {

    @ObservedObject var myTimer = MyTimer()
    @ObservedObject var settings = Settings()

   // ... other code here

    Toggle(isOn: self.$settings.muteInSilenceMode) {
        Text("Mute sound in silence mode")
    }
    .onReceive(self.settings.$muteInSilenceMode) { mute in
        self.myTimer.doSomething(with: mute) // << eg., do anything needed
    }

   // ... other code here

}
Related