Custom Annotation
Les annotations ont trois propriétés, "title", "subtitle" et "coordinate".
Ces propriétés permettent d'afficher des informations, notamment dans le callout, cette bulle qui se place au dessus de l'annotationView.
Dernièrement je voulais afficher dans une autre vue, les informations détaillées d'un objet, à partir du bouton information i du callout.
Avec la fonction calloutAccessoryControlTapped du MapViewDelegate, je ne pouvais passer que les données contenues dans title, subtitle et coordinate.
J'ai créé une classe pour personnaliser une annotation, puis caster les annotations.
CUSTOM ANNOTATION
Pour créer une annotation personnalisée, créer une nouvelle classe qui hérite des protocoles NSObject et MKAnnotation et ajouter un initialisateur.
class ObjetAnnotation: NSObject, MKAnnotation {
let title: String?
let subtitle: String?
let coordinate: CLLocationCoordinate2D
let url: String?
let adresse: String?
let horaire: String?
let tel: String?
init(title: String?, subtitle: String?, coordinate: CLLocationCoordinate2D, url: String?, adresse: String?, horaire: String?, tel: String?) {
self.title = title
self.subtitle = subtitle
self.coordinate = coordinate
self.url = url
self.adresse = adresse
self.horaire = horaire
self.tel = tel
super.init()
}
Dans cette classe, nous ajouter aux trois propriétés de bases, autant de propriétés dont nous avons besoin.
CREATION D'ANNOTATION PERSONNALISEE
Nous pouvons créer une annotation customisée
let annotation = ObjetAnnotation(title: title, subtitle: adresse, coordinate: coordinate, url: url, adresse: address, horaire: horaire, tel: tel)
self.mapView.addAnnotation(annotation)
Même pour l'utilisateur
let userAnnotation = ObjetAnnotation(title: KEY_ME, subtitle: "I'm Here 😉", coordinate: center, url: "", adresse: "", horaire: "", tel: "")
mapView.addAnnotation(userAnnotation)
Dans le callout n'apparaîtront que le title et subtitle. Mais il est possible d'ajouter une snapShotView dans le callout. Voir le post Stack Overflow
Customize MKAnnotation Callout View?
CASTER les ANNOTATIONS
Maintenant nous pouvons utiliser ce nouveau modèle d'annotation, au même titre que les autres, en apportant la précision lors de l'initialisation de l'annotation dans la méthodes viewFor annotation: MKAnnotation du MKMapViewDelegate
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let annotationView = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: "")
if let annotation = annotation as? ObjetAnnotation {
annotation.title = .....
annotation.adresse = .....
annotation.url = .....
PASSER un OBJET
Maintenant avec notre annotation, nous pouvons passer beaucoup plus d'informations.
Quand nous appuyons sur le bouton information du callout, nous pouvons afficher dans une autre vue toutes les informations de notre objet, comme dans l'exemple suivant, qui push un TableViewController.
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
let objet = view.annotation as? ObjetAnnotation
let infoTVC = self.storyboard?.instantiateViewController(identifier: "InfoTVC") as! InfoTVController
infoTVC.selectedObjet = objet
self.navigationController?.pushViewController(infoTVC, animated: true)
}
Dans ce TableViewController, nous pouvons récupérer l'url pour afficher une page internet dans une webView
let url = selectedObjet?.url
Et affecter les données de l'objet dans des cellules
cell.textLabel?.text = selectedObjet?.title
cell.detailTextLabel?.text = selectedObjet?.adresse