I have a SwiftUI project with a wrapped UIKit MapKit component for displaying annotations on a map. These annotations generate and call their respective delegate methods just fine (for example, the didSelect event). However, I need to update these markers on a updateUIView
method that gets called when a binding is updated.
The issue I have is that the updateUIView
gets called correctly when the binding gets updated, however I cannot access the MKMapView
instances' annotations
array, it is empty after I have created the annotations.
func updateUIView(_ uiViewController: MKMapView, context: Context) {
self.UpdateUIMarker()
}
func UpdateUIMarker() {
print(self.map.annotations.count)
}
On initial load of the map, the console does correctly print that there are 4 annotations associated with the MKMapView
instance, however on subsequent method calls the console prints out a count of 0.
This is the binding
@Binding var ui_markers: [UIMarker]
And the respective MKAnnotation
class I have defined
class UIMarker: NSObject, MKAnnotation, ObservableObject {
public var coordinate: CLLocationCoordinate2D
public var nr: Int
@Published public var complete: Bool
init(coordinate: CLLocationCoordinate2D, nr: Int, complete: Bool) {
self.coordinate = coordinate
self.nr = nr
self.complete = complete
super.init()
}
}
Additionally, this is the delegate method for annotations in the Coordinator
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
guard let ui_marker = annotation as? UIMarker else { return nil }
var view = mapView.dequeueReusableAnnotationView(withIdentifier: "POI")
if view == nil {
view = MKAnnotationView(annotation: ui_marker, reuseIdentifier: "POI")
}
view?.image = UIImage(named: ui_marker.complete ? "map-marker-visited" : "map-marker")
view?.frame.size = CGSize(width: 35, height: 35)
return view
}
The goal is as follows: an annotation is updated in the ui_markers
binding array (the state of the property completed
in a UIMarker
is changed), the updateUIView
picks up this change and changes the image of the respective MKAnnotation
. So far, the updateUIView
gets called correctly when the binding is updated and I can see which annotations have been completed in the ui_markers
array, the problem is in accessing that annotation in the MKMapView.annotations
array as the entire array seemingly gets emptied shortly after creation.
Let me know if additional info is required, and apologies in advance if I have missed something obvious, I am still very inexperienced with UIViewRepresentable and UIKit.
Solved: the issue was that inside the updateUIView method, I was working with the MKMapView instance that I had assigned to the class itself. Instead, all I needed to do was work with the MKMapView instance that was passed into the updateUIView method like this:
func updateUIView(_ uiViewController: MKMapView, context: Context) {
self.UpdateUIMarker(map: uiViewController)
}
func UpdateUIMarker(map: MKMapView) {
///Instead of self.map.annotations, use map.annotations
print(map.annotations.count)
}