I like to solve this by moving the data into a struct:
struct ContentData {
var isLightOn = false {
didSet {
if isLightOn {
print("Light is now on!")
} else {
print("Light is now off.")
}
// you could update another var in this struct based on this value
}
}
}
struct ContentView: View {
@State private var data = ContentData()
var body: some View {
Toggle("Light", isOn: $data.isLightOn)
}
}
The advantage this way is if you decide to update another var in the struct based on the new value in didSet, and if you make your binding animated, e.g. isOn: $data.isLightOn.animation() then any Views you update that use the other var will animate their change during the toggle. That doesn't happen if you use onChange.
E.g. here the list sort order change animates:
import SwiftUI
struct ContentData {
var ascending = true {
didSet {
sort()
}
}
var colourNames = ["Red", "Green", "Blue", "Orange", "Yellow", "Black"]
init() {
sort()
}
mutating func sort(){
if ascending {
colourNames.sort()
}else {
colourNames.sort(by:>)
}
}
}
struct ContentView: View {
@State var data = ContentData()
var body: some View {
VStack {
Toggle("Sort", isOn:$data.ascending.animation())
List(data.colourNames, id: \.self) { name in
Text(name)
}
}
.padding()
}
}