Помещение UIButton и других объектов UIControl в MKAnnotationView и разрешение взаимодействия с пользователем - PullRequest
7 голосов
/ 28 июля 2011

У меня есть пользовательский вид аннотации на карте, в котором есть UIButton, но UIButton не реагирует на нажатие. У меня есть две основные проблемы с пользовательским взаимодействием в представлении аннотации:

  1. Кнопки и другие элементы управления не реагируют.
  2. Я хочу, чтобы аннотация блокировала касания в соответствии с моей реализацией - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event - то есть, если я возвращаю ДА, то я не хочу, чтобы касания отправлялись на MKMapView (потенциально выбирая другие аннотации, ЗАКЛЮЧЕННЫЕ мой вид аннотации), в этом случае я хочу обработать касание самостоятельно.

Я удостоверился, что userInteractionEnabled установлен на YES, и я исследовал, как касания отправляются в пользовательский вид аннотации (мой подкласс MKAnnotationView) путем переопределения touchesBegan и т. Д. - но, похоже, что прикосновения обычно отменяются (хотя мне удалось получить touchesEnded несколько раз), поэтому кажется, что даже вручную будет сложно реализовать любое взаимодействие с пользователем с помощью пользовательского представления аннотации.

Есть ли у кого-нибудь идеи о том, как можно расширить взаимодействие пользователя с MKAnnotationView объектами?

Ответы [ 4 ]

5 голосов
/ 26 августа 2011

Мне удалось решить это с помощью коллеги. Решение состоит в том, чтобы переопределить - (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event. Мы предполагаем, что MKAnnotationView (от которого ваш вид аннотации должен наследовать) переопределяет это, чтобы сделать «неправильную» вещь (предположительно, чтобы выбор аннотации не блокировался между перекрывающимися аннотациями). Таким образом, вы должны переопределить его, чтобы сделать правильную вещь и вернуть соответствующий UIView, тогда система отправит ему события, и пользователь сможет взаимодействовать с ним :). Это имеет полезный (в данном случае) побочный эффект, заключающийся в том, что интерактивная аннотация блокирует выбор аннотаций, стоящих за ней.

0 голосов
/ 25 февраля 2016

Для тех, кто хочет добавить tapGesture к подпредставлению AnnotationView, тогда ответ в нижней части этого:

MKannotationView с UIButton в качестве подпредставления, кнопка не отвечает

У меня сработало:

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    if (CGRectContainsPoint(_button.frame, point)) {
        return _button;
    }
    return [super hitTest:point withEvent:event];
}
0 голосов
/ 02 апреля 2013

В дополнение к ответу jhabbott, это то, что сработало для меня. У меня есть пользовательский вид аннотации MKCustomAnnotationView, который содержит пользовательскую аннотацию CustomPin в качестве аннотации. Эта «булавка» содержит UIButton в качестве замены кнопки аксессуара, которую я хотел получить сенсорные события.

Мой hitTest метод будет выглядеть так:

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    UIView *result = [super hitTest:point withEvent:event];
    //NSLog(@"ht: %f:%f %d %@", point.x, point.y, [[event touchesForView:self] count], result);

    if ([result isKindOfClass:[MKCustomAnnotationView class]])
    {
        MKCustomAnnotationView *av = (MKCustomAnnotationView *)result;
        CustomPin *p = av.annotation;
        UIButton *ab = p.accessoryButton;
        if (p.calloutActive && point.x >= ab.frame.origin.x)
            return ab;
    }

    return result;
}

В большинстве случаев calloutActive bool, вероятно, не требуется.

0 голосов
/ 24 октября 2011

Я обнаружил, что вместо переопределения hitTest:withEvent: я мог бы просто переопределить pointInside:withEvent: и заставить его вернуть YES. Я предполагаю, что официально мне следует выполнить проверку точки-прямоугольника на предмет пересечения, чтобы убедиться, что место, по которому я касаюсь, находится внутри элемента управления, но на практике простое помещение return YES, кажется, работает отлично, все еще позволяя вам отклонить MKAnnotationView нажав от него.

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{   
    // for testing purposes
    BOOL result = [super pointInside:point withEvent:event];
    NSLog(@"pointInside:RESULT = %i", result);

    return YES;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...