简体   繁体   English

iPhone - 在iOS 3.x上检测单击和长按

[英]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. 这是一个客户端的项目,他希望它使用TouchesBegan / Moved / Ended而不是手势,因为它必须与iOS 3.0和3.1兼容,手势是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. 我必须检测单击并长按自定义元素,这是一种tableView,其中包含我们称为单元格的元素。

The rules I have to follow are: 我必须遵循的规则是:

  • A single tap has to fire a method 0.1 seconds later (lets call it cellTapped) 一次点击必须在0.1秒后触发一个方法(让我们称之为cellTapped)
  • If the control is scrolled before it is time to execute cellTapped, cancel cellTapped execution 如果在执行cellTapped之前滚动控件,则取消cellTapped执行
  • If a Long Tap is detected instead, run the longTap method not cellTapped 如果检测到长按,则运行longTap方法而不是cellTapped

This is what I have in TouchesBegan 这就是我在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. 不使用UIGestureRecognizer进行长抽头检测实际上非常简单。 You could follow a pattern something like this: 你可以遵循这样的模式:

On touchesBegan, set a BOOL flag hasLongTouchPassed to be false. 在touchesBegan上,设置一个BOOL标志hasLongTouchPassed为false。 Then, use [self performSelector:@selector(longPressDetected) withObject:nil afterDelay:1.0f] . 然后,使用[self performSelector:@selector(longPressDetected) withObject:nil afterDelay:1.0f] In longPressDetected set the hasLongTouchPassed flag to be true. longPressDetected设置hasLongTouchPassed标志是真实的。 Then, on touchesEnded, detect if hasLongTouchPassed is true, if it is then it was a long touch. 然后,在touchesEnded上,检测hasLongTouchPassed是否为true,如果是,那么它是一个长触摸。 If the user lifts their finger before the time has passed, call [NSObject cancelPreviousPerformRequestWithTarget:self] 如果用户在时间过去之前抬起手指,请调用[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. 或者,您可以在touchesBegan中存储[NSDate date] ,然后再在touchesEnded中存储日期,并进行比较以查看时间间隔是否足以被视为长按。

In addition, if you want an event to fire off X amount of time after the user pressed 此外,如果您希望事件在用户按下后触发X时间

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. 然后,在你的触摸结束方法中,你可以取消该方法,如果它还没有被触发,并调用你的tap方法,或者如果它已经被解雇则什么都不做。

PS iOS 3.0? PS iOS 3.0? Ouch...might as well write it for flip phones. 哎哟...不妨把它写成翻盖手机。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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