Как отменить UIGestureRecognizer, если нажата кнопка подпредставления - PullRequest
17 голосов
/ 03 мая 2011

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

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

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

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

Приветствия

Dave

Ответы [ 4 ]

19 голосов
/ 09 мая 2011

В конце концов, лучшим решением для меня было использование 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];
    }   
}
12 голосов
/ 01 августа 2013

Документация 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's gesture recognizers
         // from receiving the touch
        return NO;
     }
     return YES;
}

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

1 голос
/ 02 февраля 2018

Swift 3

Набор UITapGestureRecognizer

let tap = UITapGestureRecognizer(target: self, action: #selector(Class.didTap))
tap.delegate = self

UITapGestureRecognizer Метод делегата:

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
    return touch.view != buttonThatShouldCancelTapGesture
}
0 голосов
/ 03 мая 2011

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

...