iPhone iOS, как добавить UILongPressGestureRecognizer и UITapGestureRecognizer к одному элементу управления и предотвратить конфликт? - PullRequest
21 голосов
/ 16 марта 2012

Я создаю приложение для iPhone, которое позволит пользователю изменять некоторые элементы интерфейса на экране.

Как добавить распознаватель жестов касания и распознаватель жестов длинным нажатием к одному и тому же UIView?Когда я поднимаю палец после долгого нажатия, срабатывает распознаватель жестов касания.Как временно отключить распознаватель жестов касания или предотвратить его срабатывание при длительном нажатии пользователем?

Спасибо!

Ответы [ 5 ]

53 голосов
/ 16 марта 2012

Чтобы оба жеста работали вместе, используйте следующий метод делегата:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
    return YES;
}

Чтобы сделать так, чтобы долгое нажатие имело первый приоритет, выполните:

[tapGesture requireGestureRecognizerToFail:longPress];

10 голосов
/ 16 сентября 2015

Чтобы успешно объединить оба, вам нужно:

1º Добавить делегат жестов интерфейса в заголовке

@interface ViewController : ViewController <UIGestureRecognizerDelegate>

2º Создать события жестов и добавить их к представлению в исходном файле:

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(touch:)];
    [tap setNumberOfTapsRequired:1]; // Set your own number here
    [tap setDelegate:self]; // Add the <UIGestureRecognizerDelegate> protocol

    UILongPressGestureRecognizer *longTap = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longTouch:)];
    [longTap setNumberOfTapsRequired:0]; // Set your own number here
    [longTap setMinimumPressDuration:1.0];
    [longTap setDelegate:self]; // Add the <UIGestureRecognizerDelegate> protocol
    [tap requireGestureRecognizerToFail:longTap];   // Priority long

    [self.view addGestureRecognizer:tap];
    [self.view addGestureRecognizer:longTap];

3º Добавить обратные вызовы в исходном файле:

- (void) touch: (UITapGestureRecognizer *)recognizer
{
    CGPoint location = [recognizer locationInView: self.HUDview];
    if (recognizer.state == UIGestureRecognizerStateBegan)
    {
        NSLog(@"touch UIGestureRecognizerStateBegan");
    }
    if (recognizer.state == UIGestureRecognizerStateEnded)
    {
        NSLog(@"touch UIGestureRecognizerStateEnded");
        //NSLog(@"Position of touch: %.3f, %.3f", location.x, location.y);    // Position landscape
    }
}

- (void) longTouch: (UILongPressGestureRecognizer *)recognizer
{
    if (recognizer.state == UIGestureRecognizerStateBegan)
    {
        NSLog(@"longTouch UIGestureRecognizerStateBegan");
    }
    if (recognizer.state == UIGestureRecognizerStateEnded)
    {
        NSLog(@"longTouch UIGestureRecognizerStateEnded");
    }
}

4º Установить распознаватель жестов доступным:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}
8 голосов
/ 24 января 2013

В качестве альтернативного подхода, не используйте два отдельных распознавателя - просто используйте распознаватель LongPress для обоих событий:

Настройте следующим образом:

UILongPressGestureRecognizer* longPress = [ [ UILongPressGestureRecognizer alloc ] initWithTarget:self.nextResponder action:@selector(longPressEvent:)];
    categoryPanelDrag.minimumPressDuration = 0.0;

Затем обработайте следующим образом:

- (BOOL)longPressEvent:(UILongPressGestureRecognizer *)gesture {

    // _dragStarted is a class-level BOOL

    if(UIGestureRecognizerStateBegan == gesture.state) {
        _dragStarted = NO;
    }

    if(UIGestureRecognizerStateChanged == gesture.state) {
        _dragStarted = YES;
        // Do dragging stuff here
    }

    if(UIGestureRecognizerStateEnded == gesture.state) {

        if (_dragStarted == NO)
        {
            // Do tap stuff here

        }
        else
        {
            // Do drag ended stuff here
        }
    }

    return YES;

}
2 голосов
/ 30 августа 2015

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

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
    NSLog(@"%@ %ld",touch.description, touch.phase);
    [self performSelector:@selector(checkTouch:) withObject:touch afterDelay:0.5];
    return YES;
}

и

- (void)checkTouch:(UITouch *)touch{
    NSLog(@"touch phase = %ld",touch.phase);
    if (touch.phase == UITouchPhaseStationary) {
        //still holding my hand and this means I wanted longPressTouch
    }
    if (touch.phase == UITouchPhaseEnded){
        //I released my finger so it's obviously tap 
    }
}

Это может быть более простое решение, но, конечно, это зависит от проекта.

0 голосов
/ 16 марта 2012

Вы можете позаботиться об этом в коде, чтобы при длительном нажатии установить флаг, и если вызов вызывается, когда флаг установлен в true или что-то еще, не выполняйте код крана и не сбрасывайте флаг.Я не знаю лучшего способа

...