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()
}
})
}
}