views:

1458

answers:

3

I have an UIImage view that responds to touch events. I want to cancel the touch sequence if the touch goes outside of certain bounds. How can I do that?

I know that I can inspect the coordinates of the touch object, what I don't know is how to cancel the sequence. I don't see any event in the API that allows for that.

+1  A: 

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;
}
Michael Fey
Thanks, I'll give this a try when I get back to my mac. But is this going to cancel the subsequent touches events? It seems to me that after a manual call to touchesCancelled, the touchesMoved would still be called by the system.
subjective-c
Within the confines of the MoveMe sample code it will cancel the touch, but I believe you're right, touchesMoved would still be called. The more I think about it the less I think touchesCancelled is the right call.
Michael Fey
A: 

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.

A: 

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];
    }
}
David Beck