Swift version: 5.10
The built-in MKPinAnnotationView
annotation view has a rightCalloutAccessoryView
property that can be set to any kind of UIView
, including buttons. The button doesn't need to have an action attached to it, because there's a separate method that gets called when it's tapped.
First up, here's how you'd create a button inside an annotation view:
let btn = UIButton(type: .detailDisclosure)
annotationView.rightCalloutAccessoryView = btn
For context, here's a complete implementation of viewForAnnotation
that uses a button. This is taken from project 19 of Hacking with Swift, where I created a class called Capital
that implemented the MKAnnotation
protocol – you'll need to adjust this for your own annotation type:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let identifier = "Capital"
if annotation is Capital {
if let annotationView = mapView.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
return annotationView
}
}
return nil
}
When it comes to detecting taps on your button, implement the calloutAccessoryControlTapped
method. This tells you the annotation view that was tapped (from which you can pull out the annotation), the control that was tapped (in our case it's a button), and also the map view the whole thing belongs to. Here's an example:
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
let capital = view.annotation as! Capital
let placeName = capital.title
let placeInfo = capital.info
let ac = UIAlertController(title: placeName, message: placeInfo, preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "OK", style: .default))
present(ac, animated: true)
}
SPONSORED Debug 10x faster with Proxyman. Your ultimate tool to capture HTTPs requests/ responses, natively built for iPhone and macOS. You’d be surprised how much you can learn about any system by watching what it does over the network.
Sponsor Hacking with Swift and reach the world's largest Swift community!
Available from iOS 2.0 – see Hacking with Swift tutorial 19
This is part of the Swift Knowledge Base, a free, searchable collection of solutions for common iOS questions.
Link copied to your pasteboard.