UITapGestureRecognizer - одно касание и двойное касание - PullRequest
151 голосов
/ 16 января 2012

Я пытаюсь добавить 2 UITapGestureRecognizers к представлению, одно для одного касания и одно для событий двойного касания.Распознаватель с одним касанием работает как положено (сам по себе).Но я не могу заставить работать распознаватель двойного касания.

Попытался поэкспериментировать со свойствами, такими как: cancelsTouchesInView, delaysTouchesBegan и delaysTouchesEnded, но все еще не работает.

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

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

Ниже приведен последний обновленный блок кода.

// ****** gesture recognizers ******

- (void)addSingleAndDoubleTapGestureRecognizersToView:(UIView *)view
{
    // single tap    
    UITapGestureRecognizer *singleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget: tableViewController action: @selector(handleSingleTapOnView:)];                                 
    [singleTapRecognizer setNumberOfTouchesRequired:1];
    [view addGestureRecognizer: singleTapRecognizer];

    // double tap 
    UITapGestureRecognizer *doubleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget: tableViewController action: @selector (handleDoubleTapOnView:)];        
    [doubleTapRecognizer setNumberOfTouchesRequired:2];         
    [singleTapRecognizer requireGestureRecognizerToFail: doubleTapRecognizer];
    [view addGestureRecognizer: doubleTapRecognizer];         
}

- (void)handleSingleTapOnView:(id)sender
{

}

- (void)handleDoubleTapOnView:(id)sender
{

}

Ответы [ 9 ]

392 голосов
/ 16 января 2012
UITapGestureRecognizer *singleTap = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doSingleTap)] autorelease];
singleTap.numberOfTapsRequired = 1; 
[self.view addGestureRecognizer:singleTap];

UITapGestureRecognizer *doubleTap = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doDoubleTap)] autorelease];
doubleTap.numberOfTapsRequired = 2; 
[self.view addGestureRecognizer:doubleTap];

[singleTap requireGestureRecognizerToFail:doubleTap];

Примечание: Если вы используете numberOfTouchesRequired , оно должно быть .numberOfTouchesRequired = 1;

Для Swift

let singleTapGesture = UITapGestureRecognizer(target: self, action: #selector(didPressPartButton))
singleTapGesture.numberOfTapsRequired = 1
view.addGestureRecognizer(singleTapGesture)

let doubleTapGesture = UITapGestureRecognizer(target: self, action: #selector(didDoubleTap))
doubleTapGesture.numberOfTapsRequired = 2
view.addGestureRecognizer(doubleTapGesture)

singleTapGesture.require(toFail: doubleTapGesture)
40 голосов
/ 27 октября 2016

Решение Swift 3:

let singleTap = UITapGestureRecognizer(target: self, action:#selector(self.singleTapAction(_:)))
singleTap.numberOfTapsRequired = 1
view.addGestureRecognizer(singleTap)

let doubleTap = UITapGestureRecognizer(target: self, action:#selector(self.doubleTapAction(_:)))
doubleTap.numberOfTapsRequired = 2
view.addGestureRecognizer(doubleTap)

singleTap.require(toFail: doubleTap)

В строке кода singleTap.require (toFail: doubleTap) мы заставляем ожидание одного касания и обеспечиваем, чтобы событие касания не было двойным касанием.

31 голосов
/ 16 января 2012

Вам необходимо использовать requireGestureRecognizerToFail: метод. Примерно так:

[singleTapRecognizer requireGestureRecognizerToFail:doubleTapRecognizer];

15 голосов
/ 26 июля 2012

// ---- во-первых, вы должны выделить двойной и один жест касания ------- //

UITapGestureRecognizer* doubleTap = [[UITapGestureRecognizer alloc] initWithTarget : self action : @selector (handleDoubleTap:)];

UITapGestureRecognizer* singleTap = [[UITapGestureRecognizer alloc] initWithTarget : self action : @selector (handleSingleTap:)];

[singleTap requireGestureRecognizerToFail : doubleTap];
[doubleTap setDelaysTouchesBegan : YES];
[singleTap setDelaysTouchesBegan : YES];

// ----------------------- количество нажатий ---------------- //

[doubleTap setNumberOfTapsRequired : 2];
[singleTap setNumberOfTapsRequired : 1];

// ------ добавить двойное касание и однократное касание к виду или кнопке -------- //

[self.view addGestureRecognizer : doubleTap];
[self.view addGestureRecognizer : singleTap];
10 голосов
/ 17 января 2012

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

    tapCount++;
    switch (tapCount)
    {
        case 1: //single tap
            [self performSelector:@selector(singleTap:) withObject: indexPath afterDelay: 0.2];
            break;
        case 2: //double tap
            [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(singleTap:) object:indexPath];
            [self performSelector:@selector(doubleTap:) withObject: indexPath];
            break;
        default:
            break;
    }
    if (tapCount>2) tapCount=0;

Методы singleTap и doubleTap просто недействительны с NSIndexPath в качестве параметра:

- (void)singleTap:(NSIndexPath *)indexPath {
  //do your stuff for a single tap
}

- (void)doubleTap:(NSIndexPath *)indexPath {
  //do your stuff for a double tap
}

Надеюсьэто помогает

3 голосов
/ 11 июля 2016

Решение для Swift 2:

let singleTapGesture = UITapGestureRecognizer(target: self, action: #selector(handleSingleTap))
singleTapGesture.numberOfTapsRequired = 1 // Optional for single tap
view.addGestureRecognizer(singleTapGesture)

let doubleTapGesture = UITapGestureRecognizer(target: self, action: #selector(handleDoubleTap))
doubleTapGesture.numberOfTapsRequired = 2
view.addGestureRecognizer(doubleTapGesture)

singleTapGesture.requireGestureRecognizerToFail(doubleTapGesture)
1 голос
/ 10 мая 2017

Я реализовал методы UIGestureRecognizerDelegate для обнаружения как singleTap, так и doubleTap.

Просто сделайте это.

 UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleDoubleTapGesture:)];
    [doubleTap setDelegate:self];
    doubleTap.numberOfTapsRequired = 2;
    [self.headerView addGestureRecognizer:doubleTap];

    UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleSingleTapGesture:)];
    singleTap.numberOfTapsRequired = 1;
    [singleTap setDelegate:self];
    [doubleTap setDelaysTouchesBegan:YES];
    [singleTap setDelaysTouchesBegan:YES];
    [singleTap requireGestureRecognizerToFail:doubleTap];
    [self.headerView addGestureRecognizer:singleTap];

Затем реализуйте эти методы делегата.

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
    return  YES;
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
    return YES;
}
0 голосов
/ 09 июля 2014

В отношении комментария @ stanley -

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

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

0 голосов
/ 07 января 2014

Некоторые представления имеют встроенные распознаватели двойного касания (например, MKMapView).Чтобы обойти это, вам нужно реализовать UIGestureRecognizerDelegate метод shouldRecognizeSimultaneouslyWithGestureRecognizer и вернуть YES:

Сначала реализовать ваши двойные и одиночные распознаватели:

// setup gesture recognizers
UITapGestureRecognizer* singleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                                action:@selector(mapViewTapped:)];
singleTapRecognizer.delegate = self;
singleTapRecognizer.numberOfTapsRequired = 1;


UITapGestureRecognizer* doubleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                                      action:@selector(mapViewDoubleTapped:)];
doubleTapRecognizer.delegate = self;    // this allows
doubleTapRecognizer.numberOfTapsRequired = 2;
[singleTapRecognizer requireGestureRecognizerToFail:doubleTapRecognizer];

А затем реализовать:

#pragma mark UIGestureRecognizerDelegate
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer
*)otherGestureRecognizer {  return YES; }
...