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

Как отменить UIGestureRecognizer, если кнопка subview нажата

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

У меня есть scrollView набор для пейджинга и несколько subviews на каждой странице. Я добавил распознавателя жестов касания, чтобы перейти к следующей или предыдущей странице, если пользователь вступает вправо или влево от страницы.

    // Add a gesture recogniser turn pages on a single tap at the edge of a page
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGestureHandler:)];
    tapGesture.cancelsTouchesInView = NO;
    [self addGestureRecognizer:tapGesture];
    [tapGesture release];

и мой обработчик жестов:

- (void) tapGestureHandler:(UIGestureRecognizer *) gestureRecognizer {
    const CGFloat kTapMargin = 180;

    // Get the position of the point tapped in the window co-ordinate system
    CGPoint tapPoint = [gestureRecognizer locationInView:nil];

    // If the tap point is to the left of the page then go back a page
    if (tapPoint.x > (self.frame.size.width - kTapMargin)) [self scrollRectToVisible:pageViewRightFrame animated:YES];

    // If the tap point is to the right of the page then go forward a page
    else if (tapPoint.x < kTapMargin) [self scrollRectToVisible:pageViewLeftFrame animated:YES];
}

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

Приветствия

Dave

4b9b3361

Ответ 1

Решение, которое наилучшим образом помогло мне в конце концов, заключалось в том, чтобы использовать hitTest, чтобы определить, есть ли какие-либо кнопки под расположением жестов кран. Если есть, то просто игнорируйте остальную часть кода жестов.

Кажется, хорошо работает. Хотелось бы узнать, есть ли какие-либо проблемы с тем, что я сделал.

- (void) tapGestureHandler:(UIGestureRecognizer *) gestureRecognizer {
    const CGFloat kTapMargin = 180;

    // Get the position of the point tapped in the window co-ordinate system
    CGPoint tapPoint = [gestureRecognizer locationInView:nil];

    // If there are no buttons beneath this tap then move to the next page if near the page edge
    UIView *viewAtBottomOfHeirachy = [self.window hitTest:tapPoint withEvent:nil];
    if (![viewAtBottomOfHeirachy isKindOfClass:[UIButton class]]) {

        // If the tap point is to the left of the page then go back a page
        if (tapPoint.x > (self.bounds.size.width - kTapMargin)) [self scrollRectToVisible:pageViewRightFrame animated:YES];

        // If the tap point is to the right of the page then go forward a page
        else if (tapPoint.x < kTapMargin) [self scrollRectToVisible:pageViewLeftFrame animated:YES];
    }   
}

Ответ 2

Документация Apple показывает ответ:

- (void)viewDidLoad {
      [super viewDidLoad];
      // Add the delegate to the tap gesture recognizer
      self.tapGestureRecognizer.delegate = self;
}

// Implement the UIGestureRecognizerDelegate method
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:    (UITouch *)touch {
      // Determine if the touch is inside the custom subview
     if ([touch view] == self.customSubview){
         // If it is, prevent all of the delegate gesture recognizers
         // from receiving the touch
        return NO;
     }
     return YES;
}

Конечно, в этом случае customSubview будет подчиняться на странице с кнопками в ней (или даже кнопками на нем)

Ответ 3

Вы можете подклассифицировать UIView и перезаписать селектор -touchesBegan, или вы можете играть с свойством opaque для подзонов, чтобы сделать их "невидимыми" для касаний (если view.opaque = NO, представление игнорирует события касания).