如何取消一系列UITouch事件?

我有一个响应触摸事件的UIImage视图。 我想取消触摸序列,即进一步调用touchesMoved: ,如果触摸超出某些范围。 我怎样才能做到这一点?

我知道在touchesMoved:我可以检查触摸对象的坐标并忽略它,但我不知道的是如何完全取消序列。 我没有看到Apple Developer UIResponder Reference中记录的任何方法,我可以调用它来取消触摸序列。

这个解决方案可能有些麻烦,但您可以实现并手动调用

 - (void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event; 

我将这个解决方案松散地放在我对Apple的iPhone示例代码网站上的MoveMe示例应用程序进行的一些调整上,其中我修改了touchesMoved方法,如下所示:

 - (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; if ([touch view] == placardView) CGPoint location = [touch locationInView:self]; placardView.center = location; // I added the following line: [self touchesCancelled:touches withEvent:event]; return; } 

你需要调用[super touchesMoved:withEvent:]才能让超级视图从事件中清除,但更重要的是,你不需要调用[super touchesCancelled:withEvent:]

这是我在单元格上使用的,以防止在检测到滑动时被选中:

 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { if (!showingEdit) { if (IS_FAR_ENOUGH_TO_BE_A_SWIPE) { RESPOND_TO_SWIPE showingEdit = YES; [super touchesCancelled:touches withEvent:event]; } else { [super touchesMoved:touches withEvent:event]; } } } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { if (!showingEdit) { [super touchesEnded:touches withEvent:event]; } } 

尝试将UIImageView的userInteractionEnabled属性临时设置为NO

我最近遇到了同样的问题,并找到了解决问题的标准方法。 您可以使用[[UIApplication sharedApplication] beginIgnoringInteractionEvents]停止向整个应用程序提供touchesMoved事件。 当您需要再次接收触摸时,请确保使用[[UIApplication sharedApplication] endIgnoringInteractionEvents]启用它们。

我不认为这是可能的,因为我没有看到它记录在案,这些解决方案都不起作用。

“蛮力”解决方案取决于它是否适合您的需求:删除并重新初始化接收触摸或响应它们的子视图(当然要处理框架和内容)。

这段代码可以帮到你。 我在touchesMoved:方法中禁用触摸事件,我在touchesCancelled:方法中启用触摸事件

 -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; ....... ....... Your code ....... ....... //Condition when you want to disable touch event [[UIApplication sharedApplication] beginIgnoringInteractionEvents]; ....... ....... Your code ....... ....... } - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { [[UIApplication sharedApplication] endIgnoringInteractionEvents]; } 

我通过从超级视图中删除视图并将其直接添加来实现此目的。

 [view retain]; UIView *sv = view.superview; [view removeFromSuperview]; [sv addSubview:view]; [view release]; 

这会将响应者链断开到视图,因此视图上不会收到任何剩余的触摸。 下一次触摸仍将正常接收。

在iOS5上,UITouch中似乎有一个私有方法

 -(void)setSentTouchesEnded:(BOOL)ended; 

根据苹果的实施情况,它可能会停止发送事件

另一种方法是使用关联对象

 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { if ([(NSNumber *)objc_getAssociatedObject(touch, &outKey) boolValue]) return; if (sometouchisoutsideofview) { objc_setAssociatedObject(touch, &outKey, [NSNumber numberWithBool:YES], OBJC_ASSOCIATION_RETAIN); } } 

我只是想解决这样的问题,并发现她列出的所有解决方案都没有为我工作。 我可以管理的最好的是暂时忽略了触摸,但是当触摸重新进入视图时它们又恢复了。

终于解决了。

  1. 设置一个名为“disabled”的布尔标志
  2. 在touchMoved中,首先检查触摸是否在所需视图内。 如果不是,请将禁用标志设置为YES。
  3. 仍然在touchMoved中,在执行操作之前检查标志。 所以,在这一点上,如果他们不在视野之外,什么都不会发生。
  4. 在touchesEnded中,将禁用标志设置为NO。 因此,触摸序列有效地停止,直到用户抬起他们的手指。

我想这对你有用,除非你有一个特定的理由要求取消触摸序列。

您可以为UITouch创建类别。 你可以申报

 @property (nonatomic,strong,readwrite) UIView *view; 

例如,当您将touch.view更改为nil时,您可以模拟调度触摸事件的结束

您可以检查,触摸点位置是否在CGRect中 (即,点位于图像视图的矩形中)。 如果它们不在该Rect中,则触摸将被取消。

 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; CGPoint touchLocation = [touch locationInView:self.view]; if (CGRectContainsPoint(myImageView, touchLocation)) { lastPoint = [touch locationInView: myImageView]; } NSLog(@"Last :%.2f - %.2f",lastPoint.x, lastPoint.y); } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { CGPoint currentPoint; UITouch *touch = [touches anyObject]; CGPoint touchLocation = [touch locationInView:self.view]; if (CGRectContainsPoint(myImageView.frame, touchLocation)) { currentPoint = [touch locationInView: myImageView]; } }