MkMapView tap + Annotation Selection Issue
I have a MkMa开发者_如何学GopView on which I have some Annotations. When I click an annotation Its detail is opened in another view which has scroll view in bottom half of map view. When we scroll through scrollview the map centers on next annotation and its details are shown in scrollview.
My problem is that I want to add a tap gesture on Map so that when i tap on map the scrollview should hide. For this purpose I added a UiTapGesture on map which also works fine but the issue is that annotations on map no longer remain tapable. The map always goes to action of tapgesture and it never call again the selectannotation method?
How can I fix this issue????
You can tell your gesture recognizer and the map's to work simultaneously by implementing the shouldRecognizeSimultaneouslyWithGestureRecognizer
delegate method.
When creating the tap gesture, set its delegate:
tapGR.delegate = self; //also add <UIGestureRecognizerDelegate> to @interface
and implement the method:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer
:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
Now both your tap gesture method and the didSelectAnnotationView
will get called.
Assuming your tap handler gets called first, you can remove and nil the scrollview there and then the didSelectAnnotationView would create and add the scrollview. If the sequence turns out to be different, you might need to add some flags to coordinate the removal/creation.
Not a clean way but the only way I could find was checking for all visible annotations inside shouldBeginGestureRecognizer method :
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
CGPoint p = [gestureRecognizer locationInView:self.mapView];
NSLog(@"touch %f %f",p.x,p.y);
MKMapRect visibleMapRect = self.mapView.visibleMapRect;
NSSet *visibleAnnotations = [self.mapView annotationsInMapRect:visibleMapRect];
for ( MyCustomAnnotation *annotation in visibleAnnotations ){
UIView *av = [self.mapView viewForAnnotation:annotation];
if( CGRectContainsPoint(av.frame, p) ){
// do what you wanna do when Annotation View has been tapped!
return NO;
}
}
return YES;
}
I think you should do only add a gesture recognizer when the scrollview is shown. Like I do with the keyboard in the exampble below 1. When keyboard is show the mapView adds a tap gesture 2. When away I remove the gesture recognizer.
// Call this method somewhere in your view controller setup code.
- (void)registerForKeyboardNotifications
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillBeHidden:)
name:UIKeyboardWillHideNotification object:nil];
}
// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
self.tapMapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyboard)];
self.tapMapGestureRecognizer.cancelsTouchesInView = NO;
[self.parkingsMapView addGestureRecognizer:self.tapMapGestureRecognizer];
}
// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
[self.parkingsMapView removeGestureRecognizer:self.tapMapGestureRecognizer];
}
-(void) hideKeyboard{
[self.searchbar resignFirstResponder];
}
精彩评论