1

这是一个客户项目,他希望它使用 TouchesBegan/Moved/Ended 而不是手势,因为它也必须与 iOS 3.0 和 3.1 兼容,并且手势是 iOS >= 3.2。

我必须检测自定义元素上的单击和长按,该元素是一种带有我们称为单元格的元素的 tableView。

我必须遵守的规则是:

  • 单击必须在 0.1 秒后触发一个方法(我们称之为 cellTapped)
  • 如果控件在执行 cellTapped 之前滚动,取消 cellTapped 执行
  • 如果检测到 Long Tap,则运行 longTap 方法而不是 cellTapped

这就是我在 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;
  }
}

如何将长按检测添加到此逻辑?谢谢

4

2 回答 2

2

不使用 UIGestureRecognizers 的长按检测实际上相当简单。你可以遵循这样的模式:

在 touchesBegan 上,将 BOOL 标志hasLongTouchPassed设置为 false。然后,使用[self performSelector:@selector(longPressDetected) withObject:nil afterDelay:1.0f]. 在longPressDetected设置hasLongTouchPassed标志为真。然后,在 touchesEnded 上,检测是否hasLongTouchPassed为真,如果是,则为长触摸。如果用户在时间过去之前抬起手指,请致电[NSObject cancelPreviousPerformRequestWithTarget:self]

或者,您可以[NSDate date]在 touchesBegan 上存储一个日期,然后再在 touchesEnded 中存储一个日期,并比较以查看时间间隔是否足够长以被视为长按。

此外,如果您希望事件在用户按下 X 后触发

这假设您没有使用多点触控。如果是,您将必须跟踪哪个手指在哪里以及持续了多长时间。

于 2012-06-14T23:28:29.163 回答
2

我觉得你的逻辑有点倒退。您应该在触摸开始方法中添加一个长按计时器,而不是点击计时器。然后,在您的 touches end 方法中,如果该方法尚未触发,您可以取消该方法,并调用您的 tap 方法,或者如果它已经触发,则不执行任何操作。

PS iOS 3.0?哎哟……还不如写翻盖手机。

于 2012-06-14T23:38:24.147 回答