How do I detect a single tap on an instance of MKMapView
? Do I have to subclass MKMapView
and then override the touchesEnded
method?
Thanks,
-Chris
How do I detect a single tap on an instance of MKMapView
? Do I have to subclass MKMapView
and then override the touchesEnded
method?
Thanks,
-Chris
Hope this will help : How to intercept touches events on a MKMapView or UIWebView objects?
If you're just looking to get notified of tap gestures without affecting any of the other touch behavior of the map, you'll want to use a UITapGestureRecognizer
. It's super simple, just put in some code like this.
UITapGestureRecognizer* tapRec = [[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(didTapMap:)];
[theMKMapView addGestureRecognizer:tapRec];
[tapRec release];
That will call the didTapMap
whenever theMKMapView
receives a tap gesture and all the pinching, and dragging gestures will still work as they did before.
Working Perfectly on iOS 8
- (void)viewDidLoad
{
[super viewDidLoad];
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:nil];
doubleTap.numberOfTapsRequired = 2;
doubleTap.numberOfTouchesRequired = 1;
[self.mapView addGestureRecognizer:doubleTap];
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
singleTap.numberOfTapsRequired = 1;
singleTap.numberOfTouchesRequired = 1;
[singleTap requireGestureRecognizerToFail: doubleTap];
[self.mapView addGestureRecognizer:singleTap];
}
- (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer.state != UIGestureRecognizerStateEnded)
return;
//Do your work ...
}
Or depending on what you are trying to do, add an MKAnnotation
(push pin, with a callout), so you have something to tap on - and then your map delegate will receive an event eg.
mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
You cant at this time intercept touches on a map view, you can try layering an opaque view on there and see if it picks up touches...
Just add some code snippet as illustration of @tt-kilew answer. In my case, I want to point the user to itself on the map but do not want to interrupt his drag touch.
@interface PrettyViewController () <MKMapViewDelegate>
@property (weak, nonatomic) IBOutlet MKMapView *mapView;
@property (assign, nonatomic) BOOL userTouchTheMap;
@end
@implementation PrettyViewController
#pragma mark - UIResponder
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[super touchesBegan:touches withEvent:event];
self.userTouchTheMap = [[touches anyObject].view isEqual:self.mapView];
}
#pragma mark - MKMapViewDelegate
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
//We just positioning to user
if (!self.userTouchTheMap) {
CLLocationDistance radius = 5000;
[self.mapView setRegion:MKCoordinateRegionMakeWithDistance(userLocation.location.coordinate, 2*radius, 2*radius) animated:YES];
}
}
@end
Nothing I ever found worked, but I came up with this unperfect solution : In viewDidLoad
let singleTapRecognizer = UITapGestureRecognizer(target: self, action: #selector(onMapClicked))
singleTapRecognizer.delegate = self
mapView.addGestureRecognizer(singleTapRecognizer)
In delegate :
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
return touch.view!.frame.equalTo(mapView.frame)
}