I think that because MKMapAnnotationView are on top of MKMapView, they will get the touch event and respond to it (be selected) so I don't think you need to select your annotation manually.
Then, if you have a look at Advanced Gesture Recognizer WWDC 2010 video, you will see that your MKMapView will receive tap event anyway, even if it's below the annotation view. That's probably why your -(void)mapViewTapped:(UITapGestureRecognizer *)tgr
method get called.
Apart from that, I can't see why your if ([v isKindOfClass:[MKAnnotationView class]])
is never true. I do the exact same thing in my code and it works fine!
Finally, to answer your last question, if you don't want to do anything when the user is just trying to close the callout, you could keep track of a custom isCalloutOpen boolean value like this:
- (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;
}
}