I have a view, which will update once the users location changes:
...
.task(id: locationManager.currentLocation){
...
}
I have added a setting which requires the view to update even if their location hasn't. How would I act on both so that the view updates if the location changes or the setting (bool) is changed? Can I use two values within the .task()
modifier:
.task(id: locationManager.currentLocation, someBoolForSetting)
CodePudding user response:
It could be something as simple as a String
that combines the 2
.task(id: "\(locationManager.currentLocation) \(someBoolForSetting)")
Or a simple struct
if you want to do something fancier
struct TaskId: Equatable{
var location: CLLocation
var bool: Bool
}
}.task(id: TaskId(location: locationManager.currentLocation, bool: someBoolForSetting)) {
You can customize the Equatable
conformance with the second one like only trigger a change if the coordinates have changed but not the speed
CodePudding user response:
If you create an Equatable
struct that contains the Location and the Bool, you can use that as the task id, e.g.
struct Model: Equatable {
var location: CLLocation = .init() {
didSet {
print("location", location)
}
}
var someBoolForSetting: Bool = false {
didSet {
print("someBoolForSetting", someBoolForSetting)
}
}
}
struct ContentView: View {
@State private var model = Model()
var body: some View {
VStack {
Button("Update location") {
model.location = CLLocation(latitude: CLLocationDegrees.random(in: -90...90), longitude: CLLocationDegrees.random(in: -180...180))
}
.buttonStyle(.borderedProminent)
Button("toggle setting") {
model.someBoolForSetting.toggle()
}
.buttonStyle(.borderedProminent)
}
.padding()
.task(id: model) {
print("Starting Task")
try? await Task.sleep(nanoseconds: 1_000_000_000)
print("Finishing Task")
}
}
}
Starting Task
Finishing Task
location <-15.42715506,-109.30132874> /- 0.00m (speed -1.00 mps / course -1.00) @ 10/01/2023, 12:37:14 Greenwich Mean Time
Starting Task
Finishing Task
someBoolForSetting true
Starting Task
Finishing Task
someBoolForSetting false
Starting Task
Finishing Task