如何取消一系列 UITouch 事件?

发布于 2024-07-13 15:03:07 字数 394 浏览 6 评论 0原文

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

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

I have a UIImage view that responds to touch events. I want to cancel the touch sequence, i.e., further calls to touchesMoved:, if the touch goes outside of certain bounds. How can I do that?

I know that in touchesMoved: I can inspect the coordinates of the touch object and ignore it, but what I don't know is how to cancel the sequence altogether. I don't see any method documented in the Apple Developer UIResponder Reference that I can call to cancel a touch sequence.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

自由如风 2024-07-20 15:03:07

这个解决方案可能有点笨拙,但您可以实现并手动调用

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

我将此解决方案松散地基于我对 Apple iPhone 示例代码 网站,我将 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;
}

This solution may be a bit kludgy, but you could implement and manually call

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

I am basing this solution loosely on some tweaking I did to the MoveMe sample app on Apple's iPhone sample code site where I modified the touchesMoved method to look like this:

- (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;
}
笔芯 2024-07-20 15:03:07

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

Try temporary setting the UIImageView's userInteractionEnabled property to NO

你不是我要的菜∠ 2024-07-20 15:03:07

您需要调用 [super TouchsMoved:withEvent:] 以便让超级视图从事件中清除,但更重要的是,您需要调用 [超级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];
    }
}

You need to call [super touchesMoved:withEvent:] in order to let the super view clean up from the event but more importantly, you need to not call [super touchesCancelled:withEvent:].

Here's what I used on a cell to keep it from getting selected when I detected a swipe:

- (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];
    }
}
揽清风入怀 2024-07-20 15:03:07

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

I've faced the same problem recently and found a standard way to solve it.
You can use [[UIApplication sharedApplication] beginIgnoringInteractionEvents] to stop delivering touchesMoved events to your whole app. Make sure to enable them using [[UIApplication sharedApplication] endIgnoringInteractionEvents] when you need to receive touches again.

忆依然 2024-07-20 15:03:07

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

I don't think it's possible because I don't see it documented and none of these solutions work.

请远离我 2024-07-20 15:03:07

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

"Brute force" solution depending if it suits your needs: Remove and re-initialize the subview that receives the touches or responds to them (of course take care of frame and content).

如梦初醒的夏天 2024-07-20 15:03:07

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

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

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

I achieve this by removing the view from its superview and adding it straight back.

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

This breaks the responder chain to the view so any remaining touches will not be received on the view. The next touch will still be received as normal.

や三分注定 2024-07-20 15:03:07

在 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);
    }
}

On iOS5 there seems to be a private method in UITouch

-(void)setSentTouchesEnded:(BOOL)ended;

Depending on apple's implementation it could stop sending events

Another way of doing so would be using associative objects

- (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);
    }
}
眼泪也成诗 2024-07-20 15:03:07

我只是想解决这样的问题,发现没有一个解决方案列出她对我有用。 我能做到的最好的办法就是暂时忽略触摸,但当触摸重新进入视图时,它们又恢复了。

终于解决了。

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

我想这对你有用,除非你有特定的原因确实需要取消触摸序列。

I was just trying to solve something like this, and found that none of the solutions listed her worked for me. The best i could manage was temporarily ignoring the touches, but then they resumed when the touch re-entered the view.

Finally solved it.

  1. Set up a boolean flag called "disabled"
  2. In touchedMoved, first check that the touch is inside the desired view. If it isn't, set the disabled flag to YES.
  3. Still in in touchedMoved, check the flag before performing your action.
    So, at this point, nothing will happen if they're outside the view.
  4. In touchesEnded, set the disabled flag to NO. So the touch sequence is effectively halted until user lifts their finger.

I guess this will work for you unless you have a specific reason for literally needing the touch sequence cancelled.

听不够的曲调 2024-07-20 15:03:07

这段代码会对你有所帮助。 我在 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];
}

This code will help you. I disable touch event in touchesMoved: method and I am enabling touch event in touchesCancelled: method

-(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];
}
無處可尋 2024-07-20 15:03:07

您可以为 UITouch 创建类别。 您可以声明当您将 touch.view 更改为 nil 时,您可以模拟调度触摸事件的结束

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

例如,

You may create category to UITouch. You can to declare

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

And when you change touch.view to nil, for example, you can simulate end of dispatching touch events

夜空下最亮的亮点 2024-07-20 15:03:07

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

-(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];
     }
 }

You can check that, the touch point locations are in CGRect (ie. points are in Rectangle of your imageview) or not. If they are not in that Rect, the touch will be cancelled.

-(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];
     }
 }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文