web-dev-qa-db-fra.com

Personnaliser la légende MKAnnotationView

Je souhaite créer une légende MKAnnotationView personnalisée, comme indiqué dans cette image. J'ai testé plusieurs solutions mais elles ne permettent que la personnalisation des images gauche/droite et du titre/sous-titre. Quelqu'un peut-il me donner un code source ou un lien de didacticiel? 

Actuellement, je suis désemparé. S'il vous plaît aider.

enter image description here

42
Janak Nirmal

Je comprends que vous souhaitiez une épingle avec une légende personnalisée. 

Nous ne pouvons pas créer de légende personnalisée, mais nous pouvons créer une annotation avec une vue entièrement personnalisée. L'astuce consiste donc à ajouter une deuxième annotation lorsque celle-ci est sélectionnée et à donner à la deuxième vue une annotation ressemblant à une bulle de légende.

C’est la solution proposée par les utilisateurs djibouti33 et jacob-jennings dans la réponse: MKAnnotationView - Verrouiller l’affichage des annotations personnalisées pour épingler les mises à jour de l’emplacement , qui est basé à a blog post de Asynchrony Solutions. À des fins d’explication, voici quelques exemples de langage UML d’un projet forké: Annotation with custom XIB

Il s’agit d’un gros bidouillage, mais aussi de la façon la plus propre que j’ai déjà vue d’implémenter des annotations personnalisées. 

Commencez avec une classe "Contenu" NSObject qui a une coordonnée, la classe de la vue légende à utiliser (dans UML, AnnotationView, mais vous pouvez en créer davantage et les définir ici), et un dictionnaire de valeurs aléatoires avec le titre, la photo url, etc. Utilisez cette classe pour initialiser un objet "Annotation" MKAnnotation.

#import <MapKit/MapKit.h>
@interface Content : NSObject
@property (nonatomic,assign) CLLocationCoordinate2D coordinate;
// ...

@interface Annotation : NSObject <MKAnnotation, AnnotationProtocol>
-(id) initWithContent:(Content*)content;
// ...

Annotation implémente AnnotationProtocol pour annoncer qu'il souhaite gérer la création de son propre MKAnnotationView. C'est-à-dire que votre MKMapViewDelegate devrait avoir un code comme celui-ci:

- (MKAnnotationView *)mapView:(MKMapView *)aMapView viewForAnnotation:(id<MKAnnotation>)annotation 
{
    // if this is a custom annotation, delegate the implementation of the view
    if ([annotation conformsToProtocol:@protocol(AnnotationProtocol)]) {
        return [((NSObject<AnnotationProtocol>*)annotation) annotationViewInMap:mapView];
    } else {
        // else, return a standard annotation view
        // ...
    }
} 

La vue renvoyée sera de type AnnotationView, qui implémentera AnnotationViewProtocol pour annoncer qu'elle souhaite gérer la sélection/désélection. Par conséquent, dans votre contrôleur de vue cartographique, les méthodes mapView: didSelectAnnotationView: et mapView: didDeselectAnnotationView: doivent déléguer de la même manière que ce que nous avons vu auparavant.

Lorsque l'annotation est sélectionnée, une seconde annotation (CalloutAnnotation) est ajoutée. Elle suit le même comportement, mais cette fois, la vue renvoyée (CalloutView) est initialisée à partir d'un fichier XIB et contient le code Core Graphics (dans BaseCalloutView) pour animer et faire appel à.

L'initialiseur de la classe CalloutView:

- (id)initWithAnnotation:(CalloutAnnotation*)annotation
{
    NSString *identifier = NSStringFromClass([self class]);
    self = [super initWithAnnotation:annotation reuseIdentifier:identifier];
    if (self!=nil){
        [[NSBundle mainBundle] loadNibNamed:identifier owner:self options:nil];
        // prevent the tap and double tap from reaching views underneath
        UITapGestureRecognizer *tapGestureRecognizer = ...
    }
    return self;
}

Pour pouvoir envoyer un autre contrôleur de vue à partir de la vue Légende, j'ai utilisé les notifications.

La réponse SO que j’ai liée en haut contient deux projets complets mettant en œuvre ce code (les noms de classe peuvent différer). J'ai un autre projet utilisant l'UML ci-dessus à https://github.com/j4n0/callout .

49
Jano

Je sais que cette question date de 2011, mais pour les personnes qui la trouvent encore dans une recherche: Dans iOS 9, vous avez MKAnnotationView.detailCalloutAccessoryView qui remplace entièrement la légende standard.

0
bio

J'ai ajouté UIButton personnalisé dans MKAnnotationView. Et en cliquant sur ce bouton, j'ai montré popOver avec rootViewController avec la vue similaire à celle présentée ci-dessus.

0
Mahesh