Home > Mobile >  SwiftUI Conditionally trigger a toggle
SwiftUI Conditionally trigger a toggle

Time:12-02

I want the user can only click the toggle under some specific condition. So I reverse the value of "AutocorrectStatus" again under .onChange method. But it seems like the view doesn't follow this change. It still becomes on from off even the value of AutocorrectStatus is false. What should I do?

class GlobalEnvironment: ObservableObject {
    @Published var AutocorrectStatus = false   
}

struct SettingView: View {

    @EnvironmentObject var env: GlobalEnvironment

    HStack() {
        Toggle("", isOn: self.$env.AutocorrectStatus)
            .labelsHidden()
            .onChange(of: self.env.AutocorrectStatus) { _AutocorrectStatus in
                self.env.AutocorrectStatus = !self.env.AutocorrectStatus
            }

        if self.env.AutocorrectStatus {
            Text ("ON")
                .font(.system(size: 26, weight: .semibold))
                .frame(alignment: .topLeading)
        } else {
            Text ("OFF")
                .font(.system(size: 26, weight: .semibold))
                .frame(alignment: .topLeading)
        }
    }
}

CodePudding user response:

There are several ways to do this. One way is to provide the toggle a Binding that performs the necessary checks before updating the value.

var body: some View {
        HStack {
            Toggle("", isOn: self.provideAutocorrectBinding())
        }
    }
    
    func provideAutocorrectBinding() -> Binding<Bool> {
        return Binding(get: {
            return self.env.AutocorrectStatus
        }, set: { newValue in
            let isConnected = false // Your logic to check the connection
            if isConnected {
                self.env.AutocorrectStatus = newValue
            }
        })
    }

You can trigger the alert there as well:

struct ContentView: View {
    
    @EnvironmentObject var env: GlobalEnvironment
    @State private var showingAlert = false
    
    var body: some View {
        HStack {
            Toggle("", isOn: self.provideAutocorrectBinding())
        }
        .alert("Your message.", isPresented: $showingAlert) {
            Button("OK", role: .cancel) { }
        }
        
    }
    
    func provideAutocorrectBinding() -> Binding<Bool> {
        return Binding(get: {
            return self.env.AutocorrectStatus
        }, set: { newValue in
            let isConnected = false // Your logic to check the connection
            if isConnected {
                self.env.AutocorrectStatus = newValue
            } else {
                self.showingAlert.toggle()
            }
        })
    }
}
  • Related