iPhone: Detecting Tap in MKMapView
Asked Answered
H

8

25

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

Heirdom answered 14/8, 2009 at 2:22 Comment(0)
B
3

Hope this will help : How to intercept touches events on a MKMapView or UIWebView objects?

Breaux answered 10/11, 2009 at 12:27 Comment(2)
Yes, if you read in the comments there is another solution. There is actually a third way of doing this (besides sub-classing MKMapView or layering your own view on top and passing on the touches to MKMapView). Instead of subclassing MKMapView, subclass the main window and pass the touch events to both MKMapView and your view. #1122389 Haven't tried this yet but apparently performance is better and pinch to zoom still works.Heirdom
this link is no longer validThralldom
B
36

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.

Biomass answered 31/12, 2010 at 20:30 Comment(4)
For me, setting a selector didn't work, but worked when using delegate functions (gestureRecognizerShouldBegin:) BTW, although Tap and Pan work, UIPinchGestureRecognizer doesn't work, not even using delegate functions.Chindwin
I'm not sure what to tell you without any more specifics than that... Using a selector always works for me.Biomass
a colon is missing, ir should be @selector(didTapMap:)Vivie
This gesture recognizer also fires if the user double taps to zoom the map or if an annotation is selected or deselected. Usually not what you want.Lawerencelawes
R
3

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

Repossess answered 18/9, 2009 at 8:31 Comment(0)
B
3

Hope this will help : How to intercept touches events on a MKMapView or UIWebView objects?

Breaux answered 10/11, 2009 at 12:27 Comment(2)
Yes, if you read in the comments there is another solution. There is actually a third way of doing this (besides sub-classing MKMapView or layering your own view on top and passing on the touches to MKMapView). Instead of subclassing MKMapView, subclass the main window and pass the touch events to both MKMapView and your view. #1122389 Haven't tried this yet but apparently performance is better and pinch to zoom still works.Heirdom
this link is no longer validThralldom
C
3

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 ...
     }
Conservancy answered 3/4, 2015 at 10:46 Comment(0)
I
0

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...

Inchoative answered 14/8, 2009 at 2:59 Comment(0)
E
0

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
Endocrine answered 7/4, 2017 at 13:59 Comment(0)
D
0

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)
}
Darelldarelle answered 20/9, 2017 at 9:34 Comment(0)
H
0

my 2 cents for swit 5.x:

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        let v = touch.view
        let ssv = v?.superview?.superview
        if ssv === self.mapView{
            searchBar.resignFirstResponder()
        }
    }
}

it works. but honestly can break if apple changes layers of views. better a recognizer.

Haematogenesis answered 16/9, 2019 at 16:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.