Reputation: 121
There are some serious inconsistencies in answers due to Swift updating it's API spec constantly and not being graceful in it's deprecations... So I've decided to ask this question here.
My current code accounts for updating annotations through an asynchronous function that downloads an image off the internet as a remote URL. It can fetch the UIImage the data
datatype no problem. However, I don't quite understand what is happening or the reasoning as to why we need to dequeue and engineer the solution this way.
The question is, why do we need to design our annotation this way, when we can just cast an annotation view to an annotation and not worry about every update?
Please review the following code and enlighten me:
import Foundation
import UIKit
import MapKit
import CoreLocation
class MapView: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
var locationManager:CLLocationManager!
var firstCenter = false
var regionRadius: CLLocationDistance = 1000
var mapView: MKMapView!
var av:MKPinAnnotationView!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.white
mapView = MKMapView(
frame:
CGRect(
x: 0,
y: 0,
width: view.frame.width,
height: view.frame.height
)
)
mapView.mapType = MKMapType.standard
mapView.isZoomEnabled = true
mapView.isScrollEnabled = true
mapView.delegate = self
view.addSubview(mapView)
mapView.center = view.center
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.requestAlwaysAuthorization()
locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
print("Looking for locations")
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
}
}
public func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let userLocation = locations[0]
if firstCenter == false {
centerMapOnLocation(location: userLocation)
firstCenter = true
let location2d = CLLocationCoordinate2D(latitude: userLocation.coordinate.latitude, longitude: userLocation.coordinate.longitude)
let url = URL(string: "https://graph.facebook.com/" + FB.id + "/picture?width=50&height=50")
DispatchQueue.global().async {
let data = try? Data(contentsOf: url!)
DispatchQueue.main.async {
let image = UIImage(data: data!)
let a = PinAnnotation()
a.title = "Netflix and Chill"
a.coordinate = location2d
a.image = image
self.mapView.addAnnotation(a)
self.mapView.showAnnotations(self.mapView.annotations, animated: true)
}
}
}
}
public func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("Error \(error)")
}
public func centerMapOnLocation(location: CLLocation) {
let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate,regionRadius * 2.0, regionRadius * 2.0)
mapView.setRegion(coordinateRegion, animated: true)
}
internal func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "pin")
if annotationView != nil {
annotationView?.annotation = annotation
} else {
annotationView = MKAnnotationView(
annotation: annotation,
reuseIdentifier: "pin"
)
}
annotationView?.cornerRadius = 25
let anno = annotation as? PinAnnotation
annotationView?.image = anno?.image
return annotationView
}
}
class PinAnnotation: MKPointAnnotation {
var image:UIImage!
}
Thank you for your time, Chris
Upvotes: 2
Views: 572
Reputation: 26
The reason they designed it this way was for performance reasons. This is a direct quote from the their official documentation.
"For performance reasons, you should generally reuse MKAnnotationView objects in your map views. As annotation views move offscreen, the map view moves them to an internally managed reuse queue. As new annotations move onscreen, and your code is prompted to provide a corresponding annotation view, you should always attempt to dequeue an existing view before creating a new one. Dequeueing saves time and memory during performance-critical operations such as scrolling."
Upvotes: 1