0

Edit: changed the title from : "Double tap .." to "Double selection touch.."

I need to detect at least a second touch over a MKPinAnnotationView in my app. Currently I`m able to get the first touch (I'm using kvo from here: Detecting when MKAnnotation is selected in MKMapView), and it works great with the first touch), but if i tap again on the pin, nothing is called, because the selected value doesn't change. I tried the same using "mapView:didSelectAnnotationView:" that works since ios 4, but it also doesn't get called again on the second tap.

If somebody can helps me with this, it would be great!

Best Regards

Edit, add more info:

So, the touches doesn't have to be quick, if the user touches the pin, ill show a message in the title and subtitle of the annotation, if the user touch again the same pin, so I`ll do another thing with that

Yotes
  • 378
  • 3
  • 16
  • seems like a duplicate of - http://stackoverflow.com/questions/1049889/how-to-intercept-touches-events-on-a-mkmapview-or-uiwebview-objects – rishi Jan 10 '12 at 15:54
  • Well.. it doesn't seems the same to me.. maybe it could be a work around, but i`m searching something a little more direct, this solution is messy for what I want to do. But thanks for the link, if i dont find another solution, I'll try something like that. – Yotes Jan 10 '12 at 16:55

1 Answers1

5

Create a UITapGestureRecognizer and set numberOfTapsRequired to 2. Add this gesture recognizer to your instance of MKPinAnnotationView. Additionally, you will need to set your controller as the delegate of the gesture recognizer and implement -gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: and return YES to prevent your gesture recognizer from stomping on the ones used internally by MKMapView.

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation)annotation
{
    // Reuse or create annotation view

    UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTapRecgonized:)];
    doubleTap.numberOfTapsRequired = 2;
    doubleTap.delegate = self;
    [annotationView addGestureRecognizer:doubleTap];
}

- (void)doubleTapRecognized:(UITapGestureRecognizer *)recognizer
{
    // Handle double tap on annotation view
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gesture shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGesture
{
    return YES;
}

Edit: Sorry I misunderstood. What you're describing should be possible using -mapView:didSelectAnnotationView: and the gesture recognizer configured for only 1 required tap. The idea is that we're only going to add the gesture recognizer to an annotation view when it is selected. We'll remove it when the annotation view is deselected. This way you can handle the zooming in the -tapGestureRecognized: method and it's guaranteed to only be executed if the annotation was already tapped.

For this I would add the gesture recognizer as a property of your class and configure it in -viewDidLoad. Assume it is declared as @property (nonatomic, strong) UITapGestureRecognizer *tapGesture; and that we're using ARC.

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGestureRecognized:)];
}

- (void)tapGestureRecognized:(UIGestureRecognizer *)gesture
{
    // Zoom in even further on already selected annotation
}

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)annotationView
{
    [annotationView addGestureRecognizer:self.tapGesture];
}

- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)annotationView
{
    [annotationView removeGestureRecgonizer:self.tapGesture];
}
Mark Adams
  • 30,776
  • 11
  • 77
  • 77
  • Hey, thanks for the quick and complete answer.. I'm a newbie in ios development and this kind of tricks are great! I'm affraid that the title of the question is wrong.. the touches doesn't have to be consecutive.. in fact, when the user touches the pin, I'll show the title, and the subtitle will say:"Touch to zoom", so as the pin is already selected, when the user touch it again, the map will zoom to an specific region that the custom marker has inside. So it is not a quick double tap.. my title is wrong.. sorry. But thanks, i didn't know about that. Oh, code above has an error on the selector – Yotes Jan 10 '12 at 17:37
  • Well, now the only problem seems to be that tapGesture is leaking someway.. I've used two approaches, first removing from the pin and then releasing it, but the tapgesture is still there when the view dissapear (I'm looking the profiler -allocations-). I also used autorelease, but it does the same.. seems like i'm doing something wrong :( – Yotes Jan 11 '12 at 13:54
  • What does the Leaks instrument have to say? – Mark Adams Jan 11 '12 at 16:35
  • Nothing.. i have another leak, but it's not related to that. Anyway, it's not the big deal.. I can leave with that on memory :P – Yotes Jan 12 '12 at 14:28