EDIT : Will make it clearer what I am trying to achieve.
I have some annotations on a MKMapView that I want to make easy to drag. The standard Apple way to move the annotations is to tap once then quickly tap and hold and drag. The users of the app have complained that it is too difficult to do this.
So technically what I'd like to do is to use a pan gesture. The problem is that MKMapView is also using the pan gesture to move the map about.
What I would like to do is when the use does the pan gesture, check if the pan gesture starts really close to an annotation, if so then let the pan gesture handler move the annotation. I have this part working.
But if the pan gesture was not close to an annotation then pas the gesture on to MKMapView for it to be handled by it.
// EDIT END
I've a method to handle a pan gesture. This gets called as I would expect when there is a pan gesture on the MKMapView. Sometimes I would not want to handle the gesture in my method but to pass the gesture through to the MKMapView to pan/drag the map around like normal.
Here is an outline of what I've got so far. The pan gesture is being handled by the method:
-(void)panGesture:(UIPanGestureRecognizer*)sender
Depending on some logic I would like to pass this gesture through to the MKMapView (self.mapView). Can anybody share the code to do this please?
I tried [self.mapView gestureRecognizerShouldBegin:sender];
but nothing happened from this call.
- (void) addPanGesture
{
self.panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGesture:)];
self.panGesture.delegate = self;
[self.panGesture setMinimumNumberOfTouches:1];
[self.panGesture setMaximumNumberOfTouches:1];
[self.mapView addGestureRecognizer:self.panGesture];
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
BOOL result = NO;
if ((gestureRecognizer == self.panGesture) && [[otherGestureRecognizer view] isDescendantOfView:[gestureRecognizer view]])
{
result = YES;
}
return result;
}
-(void)panGesture:(UIPanGestureRecognizer*)sender
{
//some logic to see if we will handle the gesture in this method or pass gesture on to the MKMapView
return;
}
The standard Apple way to move the annotations is to tap once then quickly tap and hold and drag. The users of the app have complained that it is too difficult to do this.
I'm not think so.. :(
I'm going to write my logic, Actually It is bad thing to use pan gesture even apple provide default drag and drop facility. BTW if you are going with your way that mentioned in your question then you must need to add separate pan gesture for each and every annotation those are displaying on the map. Add it's own tag and keep same name of gesture method for all so you will easily mange it by tag. so when end-user will tap/touch on any annotation then it's method will be called and you can get touched/tapped annotation by it's own tag. write your code for drag-drop annotation only. Not sure but might be solve your problem.
I agree completely with iPatel: If possible one should use the standard Apple way, since users are used to it.
But if you really want to implement you own solution, maybe the following might work (not tested):
The MapView
has a built-in PanGestureRecognizer
(called here builInPGR
). I assume you added your own PanGestureRecognizer
(called here ownPGR
) to this MapView
.
Now the following function in the UIGestureRecognizerDelegate
protocol controls if two gesture recognisers should recognise simultaneously (see the docs):
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,
shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool
The default implementation returns false
.
You mentioned that you can drag your annotations using ownPGR
. This means that builInPGR
does not recognise the pan gesture simultaneously with ownPGR
.
If you implement now this delegate function and return true
, ownPGR
and builInPGR
should work simultaneously: builInPGR
would move the map, and ownPGR
would check, if a region close to an annotation has been tapped, and if so, would move the annotation.
Now, this delegate function gives you also a pointer to builInPGR
, the otherGestureRecognizer
.
So if ownPGR
decides to drag an annotation since it started close to it, you can set the property isEnabled
of builInPGR
to false. This lets builInPGR
transition to a cancelled state, and the map would no longer be dragged.
Of course, you had to set builInPGR.isEnabled
to true
again, when ownPGR
finishes dragging the annotation.
Once more: I don’t know if this works, but it might. And I strongly recommend to use the standard approach!
EDIT: I am sorry, I just realised that you wanted the answer in Obj-C. But, using the docs (just switch to Obj-C) it should be easy to test it in Obj-C.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With