Home > OS >  Is it possible to update a view based of two values with the .task modifier
Is it possible to update a view based of two values with the .task modifier

Time:01-11

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
  • Related