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