Reputation: 1703
I have an ObservableObject
class CurrentPosition: ObservableObject {
@Published var northEast = CLLocationCoordinate2D()
@Published var southWest = CLLocationCoordinate2D()
init(northEast: CLLocationCoordinate2D = CLLocationCoordinate2D(), southWest: CLLocationCoordinate2D = CLLocationCoordinate2D()) {
self.northEast = northEast
self.southWest = southWest
}
func updateCoordinates(from mapView: MKMapView) {
self.northEast = mapView.northEastCoordinate
self.southWest = mapView.southWestCoordinate
}
}
which I want to update from a MapView
struct MapView: UIViewRepresentable {
@Binding var weatherStations: [WeatherStation]
@Binding var selectedWeatherStation: WeatherStation?
@EnvironmentObject var currentPosition: CurrentPosition
func makeUIView(context: Context) -> MKMapView {
let map = MKMapView()
map.showsUserLocation = true
map.delegate = context.coordinator
return map
}
func updateUIView(_ uiView: MKMapView, context: Context) {
updateAnnotations(from: uiView)
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
final class Coordinator: NSObject, MKMapViewDelegate {
var control: MapView
init(_ control: MapView) {
self.control = control
}
func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
control.currentPosition.updateCoordinates(from: mapView)
}
}
}
and pass it to an AppState
object
MapView(weatherStations: $appState.appData.weatherStations,
selectedWeatherStation: $selectedWeatherStation).environmentObject(self.currentPosition)
.edgesIgnoringSafeArea(.vertical).onReceive(currentPosition.objectWillChange) { () in
self.appState.currentPosition = self.currentPosition
}}
which in turn passes it to my API client
class AppState: ObservableObject {
@Published var appData = AppData(weatherStations: [WeatherStation]())
var currentPosition: CurrentPosition! {
didSet {
api.currentPosition = self.currentPosition
}
}
}
My issues is that it gets passed each time one of my CurrentPosition
properties gets updated, meaning it first gets passed when northEast
gets updated, than when southWest
gets updated.
How can I pass it only one, when both finished updating?
Upvotes: 1
Views: 306
Reputation: 163308
The easy way is to fold it into one property using a secondary struct
, like so:
struct MapCoordinateSpan {
let northEast: CLLocationCoordinate2D
let southWest: CLLocationCoordinate2D
}
and revise your CurrentPosition
to look like this:
class CurrentPosition: ObservableObject {
@Published var span: MapCoordinateSpan
init(northEast: CLLocationCoordinate2D = CLLocationCoordinate2D(), southWest: CLLocationCoordinate2D = CLLocationCoordinate2D()) {
self.span = MapCoordinateSpan(northEast: northEast, southWest: southWest)
}
func updateCoordinates(from mapView: MKMapView) {
self.span = MapCoordinateSpan(northEast: mapView.northEastCoordinate, southWest: mapView.southWestCoordinate)
}
}
Then bind to the span
property, and pluck out the coordinates from there.
Upvotes: 2