我有一个UIImage
响应触摸事件的视图。touchesMoved:
如果触摸超出某些范围,我想取消触摸序列,即进一步调用。我怎样才能做到这一点?
我知道touchesMoved:
我可以检查触摸对象的坐标并忽略它,但我不知道如何完全取消序列。我没有看到Apple Developer UIResponder
Reference中记录的任何可以调用来取消触摸序列的方法。
我有一个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;
}
尝试将 UIImageView 的 userInteractionEnabled 属性临时设置为 NO
您需要调用[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];
}
}
我最近遇到了同样的问题,并找到了解决它的标准方法。您可以使用 [[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);
}
}
我只是想解决这样的问题,发现她列出的所有解决方案都不适合我。我能做到的最好的办法是暂时忽略触摸,但是当触摸重新进入视图时它们又恢复了。
终于解决了。
我想这对你有用,除非你有具体的理由需要取消触摸序列。
您可以为 UITouch 创建类别。你可以申报
@property (nonatomic,strong,readwrite) UIView *view;
并且当你将 touch.view 更改为 nil 时,例如,你可以模拟调度触摸事件的结束
您可以检查触摸点位置是否在CGRect中(即点在您的图像视图的 Rectangle 中)。如果它们不在该 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];
}
}