I'm currently working on a flight tracker app that displays real-time data for planes worldwide on an MKMapView. I've successfully implemented plane annotations, but the sheer number of planes on the screen causes performance issues, especially when zoomed out.
To optimize the user experience, I want to dynamically adjust the number of plane annotations based on the zoom level of the MKMapView. Similar to popular flight radar maps, I aim to display fewer planes when zoomed out and gradually increase the count as the user zooms in.
Here's a snippet of my current code for loading and displaying plane annotations:
// FUNC THAT GET'S NEEDED INFO
private func loadAnnotations() {
guard let flightsData = flights.flights else { return }
// Clear existing annotations
planeAnnotations.removeAll()
// Load annotations asynchronously
Task {
for response in flightsData.response {
let title = response.flightIata
let subtitle = response.flightIcao
if title == nil && subtitle == nil {
// Skip annotation creation only if both title and subtitle are nil or empty
print("Skipping annotation creation for response with empty title or subtitle.")
continue
} else {
if response.lat != nil && response.lng != nil {
let coordinate = CLLocationCoordinate2D(latitude: response.lat!, longitude: response.lng!)
let annotation = PlaneAnnotation(coordinate: coordinate, title: title, subtitle: subtitle, direction: response.dir ?? 0.0)
planeAnnotations.append(annotation)
} else {
print("lat or lng in nil, weird")
}
}
}
}
}
// makeUIView that adds planes
func makeUIView(context: Context) -> MKMapView {
let mapView = MKMapView()
mapView.delegate = context.coordinator
mapView.showsUserLocation = manager.showLocation
mapView.mapType = manager.mapType
DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
mapView.removeAnnotations(mapView.annotations)
mapView.addAnnotations(annotations)
})
return mapView
}
// Adding annotation on the map
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if let planeAnnotation = annotation as? PlaneAnnotation {
let identifier = "planeAnnotation"
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier)
if annotationView == nil {
annotationView = MKAnnotationView(annotation: planeAnnotation, reuseIdentifier: identifier)
annotationView?.canShowCallout = false
annotationView?.image = tintedImage(named: "plane", color: UIColor(red: 1.0, green: 0.84, blue: 0.0, alpha: 1.0))
} else {
annotationView?.annotation = planeAnnotation
}
// Rotate the annotation view based on the direction
annotationView?.transform = CGAffineTransform(rotationAngle: CGFloat(planeAnnotation.direction))
return annotationView
}
My question is: How can I dynamically adjust the number of displayed plane annotations based on the zoom level of the MKMapView? I want to ensure a smooth and responsive user experience while maintaining an appropriate number of visible planes. Any guidance or code examples would be greatly appreciated!
P.S.: Working solution is .prefix() on the flightData.responce, but it's static and won't represent the dynamic map.