I have a conditional statement to add map annotation icons/pins in the method below. The problem I\'m having is that the map is being populated with all the same icon. It sh
In case anyone needs to use MapView annotations as a tableView, i.e. have an array of points to display on map.
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let identifier = MKMapViewDefaultAnnotationViewReuseIdentifier
if let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? TrailAnnotationView {
///TrailAnnotation has an object of type trail ( can be any model you ///want ). and so is TrailAnnotationView
///inside TrailAnnotationView we extract data from trail and display it.
annotationView.trail = (annotation as? TrailAnnotation)?.trail
annotationView.annotation = annotation
return annotationView
}
let annotationView = TrailAnnotationView(annotation: annotation, reuseIdentifier: identifier)
annotationView.trail = (annotation as? TrailAnnotation)?.trail
annotationView.canShowCallout = true
return annotationView
}
This is a TrailAnnotationView
protocol AnnotationViewProtocol {
func didTapOnAnnotation()
}
class TrailAnnotationView: MKPinAnnotationView {
/*
// Only override draw() if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func draw(_ rect: CGRect) {
// Drawing code
}
*/
var trail: TrailModel? = nil
override var annotation: MKAnnotation? { didSet { configureDetailView() } }
override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
configure()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
configure()
}
}
private extension TrailAnnotationView {
func configure() {
canShowCallout = true
configureDetailView()
}
func configureDetailView() {
guard let annotation = annotation else { return }
let rect = CGRect(origin: .zero, size: CGSize(width: 300, height: 200))
let snapshotView = UIView()
snapshotView.translatesAutoresizingMaskIntoConstraints = false
if let trail = self.trail, !trail.imageUrl.isEmpty {
AppUtils.sharedInstance.fetchImageFor(path: trail.imageUrl) { (image) in
guard let imageData = image else { return }
DispatchQueue.main.async {
let imageView = UIImageView(frame: rect)
imageView.image = imageData
snapshotView.addSubview(imageView)
}
}
} else {
let options = MKMapSnapshotter.Options()
options.size = rect.size
options.mapType = .satelliteFlyover
options.camera = MKMapCamera(lookingAtCenter: annotation.coordinate, fromDistance: 250, pitch: 65, heading: 0)
let snapshotter = MKMapSnapshotter(options: options)
snapshotter.start { snapshot, error in
guard let snapshot = snapshot, error == nil else {
print(error ?? "Unknown error")
return
}
let imageView = UIImageView(frame: rect)
imageView.image = snapshot.image
snapshotView.addSubview(imageView)
}
}
detailCalloutAccessoryView = snapshotView
NSLayoutConstraint.activate([
snapshotView.widthAnchor.constraint(equalToConstant: rect.width),
snapshotView.heightAnchor.constraint(equalToConstant: rect.height)
])
}
}