Reputation: 3525
MKMapView provides the didSelectAnnotationView: method to report when the user first taps a pin. The result of this is that the map callout gets displayed. I need to let the user dismiss the map callout by tapping the pin a second time.
Unfortunately, the didSelectAnnotationView: method does not fire when the user taps a pin which is already selected.
Upvotes: 1
Views: 1300
Reputation: 1171
I had a similar problem, in that MKMapView
's selection model didn't quite match my applications requirements. To work around this, what we need is a way to recognize taps on annotation views even if they are already selected. We can accomplish this by adding a UITapGestureRecognizer
to each annotation view in the delegate method mapView:viewForAnnotation:
Depending on your interaction model, you might need to completely drive your UI using UITapGestureRecognizer
, rather than using mapView:didSelectAnnotationView:
and mapView:didDeselectAnnotationView:
For example, I'm using a map view as a user picker. As such, selecting a user should move on to the next view controller, even if that user is already selected. Selection only provides visual feedback to the user.
- (MKAnnotationView*)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
MKPinAnnotationView *annotationView = [self.mapView dequeueReusableAnnotationViewWithIdentifier:@"pinAnnotationIdentifier"];
if (annotationView == nil)
{
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:kSPUserAnnotationViewMapViewReuseIdentifier];
// need to be able to select annotations that are already selected;
UITapGestureRecognizer* tapRecognizer = [[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(annotationViewTapped:)];
[annotationView addGestureRecognizer:tapRecognizer];
}
return annotationView;
}
- (void)annotationViewTapped:(id)sender
{
UITapGestureRecognizer *tapRecognizer = (UITapGestureRecognizer*) sender;
MKPinAnnotationView *userView = (MKPinAnnotationView*) tapRecognizer.view;
[self userSelected:(MyUserModel*) userView.annotation];
}
}
Upvotes: 0
Reputation: 113777
This is a non-standard behaviour and will confuse your users. Generally a tap outside the pin area de-selects the pin.
If you really want to do this, you could use the fact that 2 pins very close together (or in the exact same location) get selected in succession by two taps. You could put a fake pin behind the real one, which doesn't show a callout. I'm not sure exactly how this would work. You'd need to have the two pins aware of each other so that the top one always showed the callout.
Upvotes: 1