Reputation: 1189
I am having trouble understanding the code for viewForAnnotation method and when it is called. My intention is to display a specific callout depending on what color the pin color is. Upon first loading the mapView, the callouts are displayed properly, however after switching view controllers, the callout buttons are not properly displayed according to the pin color. I have a hunch this might have something to do with when viewForAnnotation is called (whether it is called every time the map appears). I am unable to figure out what is wrong because I am not sure what each part of the code does.
func mapView(_ map: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if (annotation is MKUserLocation) {
return nil
}
let identifier = "pinAnnotation"
// In particular I am not sure what the code below does
if let pin = annotation as? ColorPointAnnotation {
if let view = map.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKPinAnnotationView {
view.annotation = annotation
view.pinTintColor = pin.color ?? .purple
return view
} else {
let view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
view.isEnabled = true
view.canShowCallout = true
view.pinTintColor = pin.color ?? .purple
let btn = UIButton(type: .detailDisclosure)
view.rightCalloutAccessoryView = btn
if view.pinTintColor == .red || view.pinTintColor == .green {
let button = UIButton(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
button.setBackgroundImage(UIImage(named: "car"), for: .normal)
button.addTarget(self, action: #selector(MapVC.getDirections), for: .touchUpInside)
view.leftCalloutAccessoryView = button
} else {
let button = UIButton(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
button.setBackgroundImage(UIImage(named: "other"), for: .normal)
button.addTarget(self, action: #selector(MapVC.other), for: .touchUpInside)
view.leftCalloutAccessoryView = button
}
return view
}
}
if let annotationView = map.dequeueReusableAnnotationView(withIdentifier: identifier) {
annotationView.annotation = annotation
return annotationView
} else {
let annotationView = MKPinAnnotationView(annotation:annotation, reuseIdentifier: identifier)
annotationView.isEnabled = true
annotationView.canShowCallout = true
let btn = UIButton(type: .detailDisclosure)
annotationView.rightCalloutAccessoryView = btn
if annotationView.pinTintColor == .red || annotationView.pinTintColor == .green {
let smallSquare = CGSize(width: 120, height: 120)
let button = UIButton(frame: CGRect(origin: CGPoint(x: 0,y :0), size: smallSquare))
button.setBackgroundImage(UIImage(named: "car"), for: .normal)
button.addTarget(self, action: #selector(MapVC.getDirections), for: .touchUpInside)
annotationView.leftCalloutAccessoryView = button
} else {
let button = UIButton(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
button.setBackgroundImage(UIImage(named: "other"), for: .normal)
button.addTarget(self, action: #selector(MapVC.other), for: .touchUpInside)
annotationView.leftCalloutAccessoryView = button
}
return annotationView
}
}
Upvotes: 0
Views: 345
Reputation: 20804
The method func mapView(_ map: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?
is a delegate method of MapViewDelegate
, this method is executed every time that your mapView show an Annotation in a Region, and if is implemented you can show any subclass of annotationView
as annotationView
in the map, to show custom callout you need implement this method of MapViewDelegate
//example code
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView){
let customCallout = CustomCallout(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width * 0.8, height: 50))
customCallout.backgroundColor = UIColor.red //your color here
view.addSubView(customCallout)
//adjust any param you need here
}
Hope this helps you
Upvotes: 1