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é:
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.
Je pense que c'est juste une vue personnalisée avec une broche personnalisée, quel est votre vrai problème? – Mat
Très bonne question .. Ça m'aide aussi .. Merci beaucoup Jennis .. –
Exemple de démonstration - http://stackoverflow.com/questions/27519517/button-action-in-mkannotation-view-not-working/27519673#27519673 – Kampai