1
votes

I know there is already a thread about that topic (How can I trigger an action when a swiftUI toggle() is toggled?) but I tried every answer and nothing has worked.

First my code:

struct ContentView: View {
    
    @State private var isOn = false
    
    
    var body: some View {
        
        NavigationView{
            VStack{
                ZStack {
                    Form{
                        // HERE THE IMPORTANT PART

                        Toggle(isOn: %isOn) {
                            Text(isOn ? "On" : "Off")
                            
                            /*if(isOn){
                                Text("\(sendState(state: isOn))")
                            }else{
                                Text("\(sendState(state: isOn))")
                            }*/
                              //--> that is a workaround but doesn't work for me because the function send something to the server and that should only happen when the Toggle State is changed but now the function is called every time the view is changed//


                        }
                    }
                }
            }
            
    func sendState(state: Bool){
        if state{
            mqttClient.publish("rpi/gpio", withString: "on")
            print("Published ON")
        }else{
            mqttClient.publish("rpi/gpio", withString: "off")
            print("Published OFF")
        }
    }
}

So, what I want to do is to call the function sendState(state: isOn) when I tap the toggle and the state of isOn changes to true or false. I tried willSet, didSet, own extensions for bindings and some other stuff but nothing worked like I said above.

Can anyone help me please?

1

1 Answers

4
votes

SwiftUI 2.0

Xcode 12 / iOS 14

As simple as

Toggle(isOn: $isOn) {
    Text(isOn ? "On" : "Off")
}.onChange(of: isOn) {
    self.sendState(state: $0)
}

SwiftUI 1.0+ (still valid)

A bit more complicated

Toggle(isOn: $isOn) {
    Text(isOn ? "On" : "Off")
}.onReceive([isOn].publisher.first()) {
    self.sendState(state: $0)
}