Как я могу поймать нажатие на MapView, а затем передать его распознавателям жестов по умолчанию? - PullRequest
11 голосов
/ 14 марта 2012

Вот что я хочу - пользователь нажимает на карту, мой код исполняется, а затем выполняется системный код (если пользователь щелкнул по аннотации и т.д. ...).

Я добавил простой распознаватель касаний для просмотра карты:

UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(mapViewTapped:)];
[self.mapView addGestureRecognizer:tapGestureRecognizer];
[tapGestureRecognizer release];

Внутри mapViewTapped мой код выполняется. Теперь я хочу сообщить системный код касания (например, чтобы показать выноску). Как я могу это сделать? Как пройти событие, которое я перехватил?

1 Ответ

23 голосов
/ 14 марта 2012

Один из способов - реализовать метод UIGestureRecognizerDelegate gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: и вернуть в него YES:

//add <UIGestureRecognizerDelegate> to .h to avoid compiler warning

//add this where you create tapGestureRecognizer...
tapGestureRecognizer.delegate = self;

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer 
    shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}

Теперь будет вызван ваш mapViewTapped:, а затем распознаватель вида карты вызовет его метод. Если касание было в представлении аннотации, представление карты покажет свою выноску (и метод делегата didSelectAnnotationView будет вызван, если вы его реализовали).


Другой способ, если вам нужно больше контроля, тогда вместо того, чтобы делать вышеописанное, в вашем mapViewTapped: вы можете проверить, был ли касание в представлении аннотации, а затем вручную выбрать аннотацию, которая затем покажет его выноску (и вызвать didSelectAnnotationView метод делегата):

-(void)mapViewTapped:(UITapGestureRecognizer *)tgr
{
    CGPoint p = [tgr locationInView:mapView];

    UIView *v = [mapView hitTest:p withEvent:nil];

    id<MKAnnotation> ann = nil;

    if ([v isKindOfClass:[MKAnnotationView class]])
    {
        //annotation view was tapped, select it...
        ann = ((MKAnnotationView *)v).annotation;
        [mapView selectAnnotation:ann animated:YES];
    }
    else
    {
        //annotation view was not tapped, deselect if some ann is selected...
        if (mapView.selectedAnnotations.count != 0)
        {
            ann = [mapView.selectedAnnotations objectAtIndex:0];
            [mapView deselectAnnotation:ann animated:YES];
        }
    }
}
...