Подтвердить что ты не робот

Как надежно найти правильный вид для UIGestureRecognizer?

У меня есть куча UIViews, как на изображении ниже. Красное/розовое (полупрозрачное) изображение находится поверх других.

  • У красного есть UISwipeGestureRecognizer.
  • Зеленый имеет UITapGestureRecognizer.
  • У Blue нет распознавателя.

enter image description here

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

Прикосновение к скрытым частям Green не позволяет запускать свой распознаватель (красный блокирует его).

Это проблема: я хочу, чтобы Green запускался. Как я могу это сделать?

На практике представления могут быть в любом порядке, любое число и быть под-представлениями друг друга и т.д. Но проблема одна и та же:

Как я могу надежно найти верхний вид, который может обрабатывать жест (коснитесь или проведите по экрану)?


Я пробовал с кодом ниже. Он аккуратно пересекает все представления, но он терпит неудачу, поскольку он не может знать, является ли событие частью салфетки или крана. Таким образом, метод всегда возвращает красный вид. Если я удаляю распознаватель прокрутки из Red, код работает правильно.

- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event 
{
    UIView *hitView = [super hitTest:point withEvent:event];
    if (hitView == self)
    {
        if (self.hasASwipeRecognizer)
            return self;  // What if this was a tap?
        if (self.hasATapRecognizer)
            return self; 
        else
            return nil;
    }
    else
         return hitView;
 }
4b9b3361

Ответ 1

Альтернативой добавлению распознавателя жестов к этим представлениям было бы добавить распознаватели жестов в родительское представление и надлежащим образом обрабатывать варианты использования с использованием метода метода делегата gestureRecognizer:shouldReceiveTouch:.

Определите, должен ли конкретный распознаватель получать касание и вернуть YES. Например, если распознающий признак признака является распознающим салфеткой, тогда проверьте, находится ли точка касания в зеленом виде и возвращает YES. Верните NO в противном случае.

Если есть похожие распознаватели жестов, я предлагаю вам сохранить ссылку и подтвердить ее.

Использование

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    CGPoint pointInView = [touch locationInView:gestureRecognizer.view];

    if ( [gestureRecognizer isMemberOfClass:[UITapGestureRecognizer class]] 
        && CGRectContainsPoint(self.blueView.frame, pointInView) ) {
        return YES;
    } 

    if ( [gestureRecognizer isMemberOfClass:[UISwipeGestureRecognizer class]] 
        && CGRectContainsPoint(self.greenView.frame, pointInView) ) {
        return YES;
    }

    return NO;
}

Ответ 2

Одним из возможных решений было бы добавить распознаватель жестов к красному представлению, а затем всякий раз, когда вы получите кран, проверьте, пересекается ли точка перехода с зеленым видом. Если да, перейдите к этому виду. Если нет, игнорируйте краны.

Ответ 3

Мои решения:

-(void)handleGesture:(UIGestureRecognizer*)gestureRecognizer {
    CGPoint touchPoint = [tapGestureRecognizer locationInView:viewUnderTest];
    if ([viewUnderTest pointInside:touchPoint withEvent:nil]) {
        NSLog(@"Hit done in view under test");
    }
}