简体   繁体   中英

iPhone - detecting single tap and long tap on iOS 3.x

This is a project for a client and he wants it to use TouchesBegan/Moved/Ended instead of gestures, because it has to be compatible with iOS 3.0 and 3.1 too and gestures are iOS >= 3.2.

I have to detect single tap and long tap on a custom element that is a kind of tableView with elements we call cells.

The rules I have to follow are:

  • A single tap has to fire a method 0.1 seconds later (lets call it cellTapped)
  • If the control is scrolled before it is time to execute cellTapped, cancel cellTapped execution
  • If a Long Tap is detected instead, run the longTap method not cellTapped

This is what I have in TouchesBegan

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

  self.isScrolling = NO;

  // if single tap detected, fire method within 0.1 seconds
  if ([self elementIsTapped:touches]) {
             [self performSelector:@selector(cellTapped:)
                   withObject:nil
                   afterDelay:0.1];
  }

}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{


  if (self.isScrolling == NO) {
        // started scrolling, cancel single tap method that was about to be executed 
        [NSObject cancelPreviousPerformRequestsWithTarget:self 
                                                 selector:@selector(cellTapped:)
                                                   object:nil];
        self.isScrolling = YES;
  }
}

How do I add long tap detection to this logic? thanks

Long-tap detection without use of the UIGestureRecognizers is actually fairly simple. You could follow a pattern something like this:

On touchesBegan, set a BOOL flag hasLongTouchPassed to be false. Then, use [self performSelector:@selector(longPressDetected) withObject:nil afterDelay:1.0f] . In longPressDetected set the hasLongTouchPassed flag to be true. Then, on touchesEnded, detect if hasLongTouchPassed is true, if it is then it was a long touch. If the user lifts their finger before the time has passed, call [NSObject cancelPreviousPerformRequestWithTarget:self]

Alternatively, you could instead store a date with [NSDate date] on touchesBegan, and then again in touchesEnded, and compare to see if the time interval is long enough to be considered a long-press.

In addition, if you want an event to fire off X amount of time after the user pressed

This assumes you are not using multi-touch. If you are, you'll have to track which finger is where and for how long.

I think your logic is a bit backwards. You should add a timer for the long press in your touches began method instead of a timer for tap. Then, in your touches end method you can cancel the method if it hasn't fired yet, and call your tap method, or do nothing if it has fired already.

PS iOS 3.0? Ouch...might as well write it for flip phones.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM