determine if MKMapView was dragged/moved
The code in the accepted answer fires when the region is changed for any reason. To properly detect a map drag you have to add a UIPanGestureRecognizer. Btw, this is the drag gesture recognizer (panning = dragging).
Step 1: Add the gesture recognizer in viewDidLoad:
-(void) viewDidLoad {
[super viewDidLoad];
UIPanGestureRecognizer* panRec = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(didDragMap:)];
[panRec setDelegate:self];
[self.mapView addGestureRecognizer:panRec];
}
Step 2: Add the protocol UIGestureRecognizerDelegate to the view controller so it works as delegate.
@interface MapVC : UIViewController <UIGestureRecognizerDelegate, ...>
Step 3: And add the following code for the UIPanGestureRecognizer to work with the already existing gesture recognizers in MKMapView:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
Step 4: In case you want to call your method once instead 50 times per drag, detect that "drag ended" state in your selector:
- (void)didDragMap:(UIGestureRecognizer*)gestureRecognizer {
if (gestureRecognizer.state == UIGestureRecognizerStateEnded){
NSLog(@"drag ended");
}
}
This is the only way that worked for me that detects pan as well as zoom changes initiated by user:
- (BOOL)mapViewRegionDidChangeFromUserInteraction
{
UIView *view = self.mapView.subviews.firstObject;
// Look through gesture recognizers to determine whether this region change is from user interaction
for(UIGestureRecognizer *recognizer in view.gestureRecognizers) {
if(recognizer.state == UIGestureRecognizerStateBegan || recognizer.state == UIGestureRecognizerStateEnded) {
return YES;
}
}
return NO;
}
static BOOL mapChangedFromUserInteraction = NO;
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
{
mapChangedFromUserInteraction = [self mapViewRegionDidChangeFromUserInteraction];
if (mapChangedFromUserInteraction) {
// user changed map region
}
}
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
if (mapChangedFromUserInteraction) {
// user changed map region
}
}