Search code examples
xcodeswiftuiwatchos

Changing all toggle's states (on/off) with 2 buttons


I am new to the WatchOS world and because of that I am in need of some help getting past a point where, even with tutorials, I seem to not be able to do what I am needing to do.

I have a simple watchOS app. Basically its a list with toggles and 2 buttons. What I am wanting to do is, when clicking on said button, have all the toggles change to "off" state. Likewise, the other button will put them all to the "on" state.

Here is my code so far (some code was removed):

import SwiftUI

struct User: Decodable {
    var theID: String
    var name: String
    var description: String
    var isOn: Bool
}

var body: some View {
    List{
        ForEach($users, id: \.theID) { $item in
            HStack {
                Toggle(isOn: $item.isOn) {
                    Label {
                        Text(item.description)
                            .frame(maxWidth: 85)
                            .frame(maxHeight: 100)
                            .frame(maxWidth: .infinity, alignment: .trailing)
                    } icon: {
                        if item.name == "J" {
                            Image("imgJayden")
                                .scaledToFill()
                            
                        } else if item.name == "T" {
                            Image("imgTab")
                                .scaledToFill()
                        } else {
                            Image("imgBoth")
                                .scaledToFill()
                        }
                    }
                    .onChange(of: item.isOn) { value in
                        if (rndCnt == 0) {
                            if (value) {
                                //print("tunning on")
                                sendJsonData(a: item.theID, b: item.name, c: item.description, d: item.isOn)
                            } else {
                                //print("turning off")
                                sendJsonData(a: item.theID, b: item.name, c: item.description, d: item.isOn)
                            }
                            
                            rndCnt = 1
                        } else {
                            rndCnt = 0
                        }
                    }
                }
            }.padding(2)
        }
        List{
            HStack (alignment: .center, spacing: 50){
                Button {
                    }label: {
                        Image("on")
                            .scaledToFill()
                            .frame(maxWidth: .infinity, alignment: .center)
                    }
                    .onTapGesture {
                        print("turned all on!")
                    }
                Button {
                    }label: {
                        Image("off")
                            .scaledToFill()
                            .frame(maxWidth: .infinity, alignment: .center)
                    }
                    .onTapGesture {
                        print("turned all off!")
                    }
            }
        }
    }
    .onAppear(perform: loadData)
}
    
    func loadData() {
        guard let url = URL(string: "http://192.168.1.1:81/data.php?data=ALL") else {
            print("Invalid URL")
            
            return
        }
        
        let request = URLRequest(url: url)
        
        URLSession.shared.dataTask(with: request) {data, response, error in
            if let data = data {
                let decoder = JSONDecoder()
                
                decoder.dateDecodingStrategy = .iso8601
                
                if let decodedResponse = try?
                    decoder.decode([User].self, from: data) {
                    DispatchQueue.main.async {
                        self.users = decodedResponse
                    }
                    
                    return
                }
            }
            
            print("Fetch failed: \(error?.localizedDescription ?? "Unknown error....")")
        }.resume()
    }

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

For my list I have the .onAppear(perform: loadData) which is what populates the toggles with the data (thats in function loadData. Now I'm at a standstill on how to loop through all the toggles and set them all to either on or off depending on which button was pressed.

Would be great if someone could help me out on this!


Solution

  • remove the onTapGesture for the Button, they don't need it they are buttons. Use this example code to turn all users Toggle on/off.

     List{
         HStack (alignment: .center, spacing: 50){
             Button {
                 print("turned all on!")
                 users.indices.forEach { users[$0].isOn = true } // <-- here
                 // alternative
                 // for i in users.indices { users[i].isOn = true }
             }label: {
                 Image("on")
                     .scaledToFill()
                     .frame(maxWidth: .infinity, alignment: .center)
             }
             Button {
                 print("turned all off!")
                 users.indices.forEach { users[$0].isOn = false }  // <-- here
             }label: {
                 Image("off")
                     .scaledToFill()
                     .frame(maxWidth: .infinity, alignment: .center)
             }
         }.buttonStyle(.bordered)  // <-- here
     }