5
votes

I have an iOS app with custom annotations.

  1. I want to be able to tap an MKAnnotationView once to show it's callout (works fine)
  2. and then I want to tap the MKAnnotationView a second time to de-select the annotation and hide the callout for that annotation (works in iOS5 but not iOS6).

I understand that didSelectAnnotationView is only supposed to be invoked for the initial selection of an annotation. ([1]: Selecting a MapView Annotation Twice ), and based on this article and others I've read ([2]: ios mapkit closing annotation callouts by tapping the map), it looks like detecting any additional tap on an MKAnnotationView after it is selected require a UITapGestureRecognizer.

So, I'm using a UITapGestureRecognizer and I am properly detecting additional taps on my annotation views when they're already selected, and I'm calling deselectAnnotation when I recognize the tap and I'm hiding/de-selecting the callout/annotation respectively. It works great in iOS5, but it only half works in iOS6

In iOS6 the tap gesture recognizer is invoked, and I call my code to hide the callout and de-select the annotation and everything's fine, but then the selectAnnotationView method gets called somehow and so my callout shows up again and my annotation gets selected again.

What I assume to be happening is that immediately after I do my de-selection of the annotation view in my tap gesture recognizer, the tap event is still active, the mapView detects the touch event and invokes selectAnnotationView, and so the annotation that I just de-selected is now being selected again.

I have no idea why it only happens in iOS6, but I'm hoping for input on any other ideas for handling my desired behavior.

1

1 Answers

0
votes

I don't know if you still got your problem (i hope not since your post is a little bit old). But in case some people got the same problem one solution for deselecting the annotation and avoiding mapKit to reselect it is to add a little delay before deselecting the annotation.

- (void)annotationTap:(UIGestureRecognizer *)gesture
{
    MKAnnotationView *mkav = (MKAnnotationView *)gesture.view;
    //Add a small delay to deselect
    [self performSelector:@selector(deselectAnnotation:)  withObject:mkav.annotation afterDelay:0.3];
    [gesture.view removeGestureRecognizer:gesture];
}


- (void)deselectAnnotation:(id<MKAnnotation>)annotation
{
    [self.mapView deselectAnnotation:annotation animated:YES];
}

And in case the user deselect the annotation on map tap donMt forge to remove the gesture with this code

- (void) mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view {
         for (UIGestureRecognizer *recognizer in view.gestureRecognizers) {
             [view removeGestureRecognizer:recognizer];
         }
}