Empêchez les events tactiles sur MKMapView d'être détectés lorsqu'une MKAnnotation est sélectionnée

J'ai un UITapGestureRecognizer qui cachera et montrera une barre d'outils au-dessus de mon MKMap quand l'user tape la carte – simple.

Cependant, lorsque l'user tape sur une MKMapAnnotation, je ne veux pas que la carte réponde à un tapement de la manière normale (ci-dessus). De plus, lorsque l'user appuie ailleurs sur la carte pour désélectionner une légende MKAnnotation, je ne souhaite pas non plus que la barre d'outils réponde. Ainsi, la barre d'outils ne doit répondre qu'en l'absence de MKAnnotations dans l'état sélectionné. Il ne devrait pas non plus répondre lorsque l'user clique directement sur une annotation.

Jusqu'à présent, j'essaie l'action suivante qui réagit au geste du tap sur la carte – cependant la vue d'annotation n'est jamais détectée (la première instruction if) et aussi, la vue d'annotation est également lancée indépendamment de cette méthode.

-(void)mapViewTapped:(UITapGestureRecognizer *)tgr { CGPoint p = [tgr locationInView:self.mapView]; UIView *v = [self.mapView hitTest:p withEvent:nil]; id<MKAnnotation> ann = nil; if ([v isKindOfClass:[MKAnnotationView class]])<---- THIS CONDITION IS NEVER MET BUT ANNOTATIONS ARE SELECTED ANYWAY { //annotation view was tapped, select it… ann = ((AircraftAnnotationView *)v).annotation; [self.mapView selectAnnotation:ann animated:YES]; } else { //annotation view was not tapped, deselect if some ann is selected... if (self.mapView.selectedAnnotations.count != 0) { ann = [self.mapView.selectedAnnotations objectAtIndex:0]; [self.mapView deselectAnnotation:ann animated:YES]; } // If no annotation view is selected currently then assume control of // the navigation bar. else{ [self showToolBar:self.navigationController.toolbar.hidden]; } } } 

J'ai besoin de contrôler le lancement de l'appel d'annotation par programmation et de détecter quand l'événement tap a frappé une annotation afin d'y parvenir.

Toute aide serait appréciée.

Je pense que vous findez les liens suivants très utiles:

http://blog.asynchrony.com/2010/09/building-custom-map-annotation-callouts-part-2/

Comment rendre un MKAnnotationView tactile?

Le premier lien discute (entre autres choses) comment empêcher la propagation des touches aux annotations afin qu'elles répondent sélectivement, et la seconde comment détecter les touches.

Je pense que parce que MKMapAnnotationView est au dessus de MKMapView, ils recevront l'événement tactile et y répondront (être sélectionné) donc je ne pense pas que vous ayez besoin de sélectionner votre annotation manuellement.

Ensuite, si vous jetez un coup d'œil à la video Advanced Gesture Recognizer WWDC 2010, vous verrez que votre MKMapView recevra quand même l'événement tap, même s'il se trouve en dessous de l'affichage des annotations. C'est probablement pourquoi votre méthode -(void)mapViewTapped:(UITapGestureRecognizer *)tgr est appelée.

En dehors de cela, je ne vois pas pourquoi votre if ([v isKindOfClass:[MKAnnotationView class]]) n'est jamais vrai. Je fais exactement la même chose dans mon code et ça marche bien!

Enfin, pour répondre à votre dernière question, si vous ne voulez rien faire lorsque l'user essaie juste de fermer la légende, vous pouvez suivre une valeur booleanne isCalloutOpen personnalisée comme ceci:

 - (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view { //some code _isCalloutOpen = YES; } - (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view { // delay the reset because didDeselectAnnotationView could (and is often) called before your gesture recgnizer handler method get called. [self performSelector:@selector(resetCalloutOpenState) withObject:Nil afterDelay:0.1]; } - (void)resetCalloutOpenState { _isCalloutOpen = NO; } - (void)mapViewTapped:(UITapGestureRecognizer *)tgr { if (_isCalloutOpen) { return; } }