UITapGestureRecognizer-один кран и двойной кран
Я пытаюсь добавить 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 ответов:
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 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) мы заставляем один кран ждать и убедитесь, что событие крана не является двойным нажатием.
необходимо использовать метод requireGestureRecognizerToFail:. Что-то вроде этого:
[singleTapRecognizer requireGestureRecognizerToFail:doubleTapRecognizer];
// - - - - во-первых, вы должны выделить двойной и один жест крана-------//
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];
Не уверен, что это именно то, что вы ищете, но я сделал одно/два нажатия без распознавателей жестов. Я использую его в 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 }
надеюсь, что это помогает
решение для 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)
я реализовал методы 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; }
некоторые представления имеют там собственные распознаватели двойного нажатия, встроенные (
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; }
в отношении комментария @stanley -
Не пытайтесь использовать жесты касания для выбора строк для работы в
UITableView
поскольку он уже имеет полную обработку крана....но вы должны установить "отменяет прикосновения в поле зрения" на " нет " на ваших распознавателей жестов одного крана или он никогда не получит события крана.