Как обнаружить краны и двойной кран в то же время с помощью UITapGestureRecognizer?

Например, у меня есть представление, где я хочу два разных жестов:

нажмите, чтобы выполнить действие A. дважды нажмите, чтобы выполнить действие B.

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

Пример:

_tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGestureRecognized:)];
_tapGestureRecognizer.numberOfTouchesRequired = 1;
_tapGestureRecognizer.numberOfTapsRequired = 1;
[self addGestureRecognizer:_tapGestureRecognizer];

_doubleTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTapGestureRecognized:)];
_doubleTapGestureRecognizer.numberOfTouchesRequired = 1;
_doubleTapGestureRecognizer.numberOfTapsRequired = 2;
[self addGestureRecognizer:_doubleTapGestureRecognizer];

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

Ответ 1

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

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

Ответ 2

В быстрых 3 и быстрых 4:

let singleTap = UITapGestureRecognizer(target: self, action: #selector(doSingleTap))
singleTap.numberOfTapsRequired = 1

self.view.addGestureRecognizer(singleTap)

let doubleTap = UITapGestureRecognizer(target: self, action: #selector(doDoubleTap))
doubleTap.numberOfTapsRequired = 2

self.view.addGestureRecognizer(doubleTap)

singleTap.require(toFail: doubleTap)

Ответ 3

   {  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];
        [self.headerView addGestureRecognizer:singleTap];
  }  
        - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
            return  YES;
        }

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

Создайте распознаватели жестов внутри любого метода, который вы хотите. Например, если вы хотите, чтобы жест жесткости для вашего headerView в tableView создавал те жесты касания внутри

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section

И ваш класс должен реализовать UIGestureRecognizerDelegate. Вышеупомянутые два метода этого класса делегата.

Ответ 4

Я нашел решение для задержки одиночного нажатия, используя ответ XCode Monkey. Используя этот подход, вы можете настроить в миллисекундах порог между одним и двойным нажатием. Этот метод использует простой UIButton и NSTimer для различения одиночного и двойного крана.

@property NSTimer       *tapTimer;
@property BOOL           isDoubleTap;

  UIButton *yourButton = [UIButton new];
  yourButton.frame = // set your frame
  [yourButton addTarget:self action:@selector(handleTap:) forControlEvents:UIControlEventTouchUpInside];
  [self.view yourButton];


-(void)handleTap:(UIButton*)button
{
  [self.tapTimer invalidate];

  if (self.isDoubleTap)
  {
    [self doDoubleTap];
    return;
  }
  self.isDoubleTap = YES;
  // CHANGE THE 0.3 SECOND THRESHOLD BETWEEN SINGLE/DOUBLE TAP TO YOUR HEART CONTENT
  self.tapTimer = [NSTimer scheduledTimerWithTimeInterval:0.3 target:self selector:@selector(doSingleTap) userInfo:nil repeats:NO];
}

-(void)doSingleTap
{
  self.isDoubleTap = NO;
}

-(void)doDoubleTap
{
  self.isDoubleTap = NO;
}