Как я могу поймать tap на MapView, а затем передать его распознающим признакам по умолчанию?

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

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

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

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

Ответ 1

Один из способов - реализовать метод 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 delegate):

-(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];
        }
    }
}