2011-11-05 3 views
41

Je souhaite créer une légende MKAnnotationView personnalisée, comme illustré 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 s'il vous plaît me donner un code source ou un lien tutoriel pour cela?Personnalisation de la légende MKAnnotationView

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

enter image description here

+0

Je pense que c'est juste une vue personnalisée avec une broche personnalisée, quel est votre vrai problème? – Mat

+1

Très bonne question .. Ça m'aide aussi .. Merci beaucoup Jennis .. –

+0

Exemple de démonstration - http://stackoverflow.com/questions/27519517/button-action-in-mkannotation-view-not-working/27519673#27519673 – Kampai

Répondre

49

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

Nous ne pouvons pas créer une 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 la première est sélectionnée, et à faire apparaître la deuxième vue d'annotation comme une bulle d'appel.

C'est la solution affiché par les utilisateurs djibouti33 et jacob-jennings dans la réponse: MKAnnotationView - Lock custom annotation view to pin on location updates, qui à son tour est basée dans un blog post de Solutions asynchronisme. Pour des raisons d'explication, voici quelques UML d'un projet forké: Annotation with custom XIB

Ceci est un grand bidouillage, mais aussi le moyen le plus propre que j'ai vu pour mettre en œuvre des annotations personnalisées. Commencez avec une classe "Content" NSObject qui a une coordonnée, la classe de la vue de légende à utiliser (dans le UML est AnnotationView, mais vous pouvez en créer plus et les définir ici), et un dictionnaire de valeurs aléatoires avec le titre, l'URL de la photo, etc. Utilisez cette classe pour initialiser un objet MKAnnotation "Annotation".

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

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

L'annotation met en œuvre AnnotationProtocol d'annoncer qu'elle veut gérer la création de son propre MKAnnotationView. Autrement dit, votre MKMapViewDelegate devrait avoir le code comme ceci:

- (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 retournée sera de type AnnotationView, qui met en œuvre AnnotationViewProtocol d'annoncer qu'elle veut gérer la sélection/désélection. Par conséquent, dans votre contrôleur de vue de carte, les méthodes mapView: didSelectAnnotationView: et mapView: didDeselectAnnotationView: devraient déléguer de la même manière que ce que nous avons vu auparavant. Lorsque l'annotation est sélectionnée, une deuxième annotation (CalloutAnnotation) est ajoutée, qui suit le même comportement, mais cette fois, la vue renvoyée (CalloutView) est initialisée à partir d'une XIB et contient le code Core Graphics (dans BaseCalloutView) à animer et répliquer une légende.

Le 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 pousser un autre contrôleur de vue de la vue de détail je notifications.

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

+0

Bonjour, Merci pour le merveilleux travail que vous avez accompli. J'essaye de créer une annotation pourquoi deux boutons dedans. Lorsque je clique sur le bouton, la méthode handleTouch de ma sous-classe CalloutView est appelée. Mais l'expéditeur est un UITapGestureRecognizer avec l'annotation dans la propriété d'affichage. Je devais avoir mon bouton dans le sender.view? Est-ce un problème bien connu. Ou je fais quelque chose de mal? –

+0

Oui, c'est connu, vérifiez https://github.com/j4n0/callout/issues/1 pour une solution. – Jano

+0

Je suis confronté à un problème pour mettre en œuvre ce code peut quelqu'un m'aider .. –

0

J'ai ajouté un UIButton personnalisé dans MKAnnotationView. Et au clic de ce bouton, j'ai montré popOver avec rootViewController avec la vue similaire à celle que vous avez montré ci-dessus.