# 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?](https://stackoverflow.com/questions/30793315/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
``` 






