如何将 touchesBegan 和 touchesEnded 限制为仅一次触摸?

Posted

技术标签:

【中文标题】如何将 touchesBegan 和 touchesEnded 限制为仅一次触摸?【英文标题】:How to restrict the touchesBegan and touchesEnded to one touch only? 【发布时间】:2012-03-22 07:29:56 【问题描述】:

我有一个包含两个子视图的视图:

    一个 UIImageView 一个小的自定义视图,就像一个带有可旋转指针的时钟。

我已经在自定义类时钟视图的 touchesBegan 和 touchesMoved 中编写了手轮旋转的代码。

这个自定义视图放置在图像上,我在 imageView 中添加了两指缩放、旋转、panGesture。

现在我的问题是,每当我的两根手指之一触摸这个时钟视图的指针时,它们就会移动和旋转,这是我不想要的。

我只想在我对他们做单指手势而不是在其后面的图像上做两指手势时限制他们的触摸。

编辑:这是我添加手势的代码

UIPanGestureRecognizer *panGesture = [[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)] autorelease];
panGesture.maximumNumberOfTouches = 2;
panGesture.minimumNumberOfTouches = 2;
[self.imageView addGestureRecognizer:panGesture];

【问题讨论】:

【参考方案1】:

UIGestureRecognizer 的方法-(NSUInteger)numberOfTouches 可以告诉您在您的视图上放置了多少触摸。这个Event Handling Guide也可以帮助你:)

另一种方法是UITapGestureRecognizer,可以使用numberOfTouchesRequired 进行配置,以将一个识别器限制为特定数量的手指。

编辑

如果另一个手势识别器处于活动状态,我建议您使用私有 BOOL 来锁定与其中一个手势识别器的交互。

借助 XCode 4 及更高版本中可用的新 LLVM 编译器,您可以在实现 (.m) 文件中的默认类别中声明 @private 变量:

@interface YourClassName() 
  @private:
    BOOL interactionLockedByPanRecognizer;
    BOOL interactionLockedByGestureRecognizer;

@end

@implementation YourClassName
  ... your code ...
@end

你处理平移交互的方法(我假设你会在最后做一些动画来移动东西):

- (void)handlePan:(id)sender

  if (interactionLockedByGestureRecognizer) return;

  interactionLockedByPanRecognizer = YES;
  ... your code ...
  [UIView animateWithDuration:0.35 delay:0.0 options:UIViewAnimationCurveEaseOut
                 animations:^
                   [[sender view] setCenter:CGPointMake(finalX, finalY)];
                  
                 completion:^( BOOL finished ) 
                   interactionLockedByPanRecognizer = NO;
                 
 ];

现在您只需检查您的touchesBegantouchesMovedtouchesEnded 内部是否交互被 UIPanGestureRecognizer 锁定:

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

  if (interactionLockedByPanRecognizer) return;
  interactionLockedByGestureRecognizer = YES;
  ... your code ...

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

  if (interactionLockedByPanRecognizer) return;
  ... your code ...

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event

  if (interactionLockedByPanRecognizer) return;
  ... your code ...
  interactionLockedByGestureRecognizer = NO;

【讨论】:

我已将添加到图像的手势限制为两次(最小和最大)触摸,但是当两次触摸之一落在自定义视图上并且自定义视图在其触摸事件中获取它时,问题就出现了。 如果与您的 UIImageView 发生交互,您是否考虑过将 UIGestureRecognizer 锁定在“时钟视图”上的 BOOL? 不,我不能请您详细说明一下吗? 你能发布一些你的 UIGestureRecognizer 如何处理交互的代码吗?我可以看看它。 感谢您提供如此详细的回答。

以上是关于如何将 touchesBegan 和 touchesEnded 限制为仅一次触摸?的主要内容,如果未能解决你的问题,请参考以下文章

你如何知道在 touchesBegan 中被触摸的对象是啥?

UIScrollView touchesBegan

touchesBegan,如何获得所有的接触,而不仅仅是第一次或最后一次?

在 `touchesBegan:withEvent:` 之后禁用所有 UIPanGestureRecognizer

TouchesBegan 总是返回错误的 UIView

如何将 touchesBegan 和 touchesEnded 限制为仅一次触摸?