简体   繁体   中英

MkMapView tap + Annotation Selection Issue

I have a MkMapView 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];
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM