3

I'm working on a simple note-taking/painting app. I have a view controller that works like a paper/canvas. In it I want to implement UISwipeGestureRecognizer, for example, when the user quickly wants to show the menu he or she can swipe upwards instead of hitting my "edit" button, or maybe swipe left or right when he/she wants to change paper/note.

The problem is, when the user swipes (with two fingers) the app also draws a short line in the same direction.

I have implemented the UISwipeGestureRecognizer like this:

UISwipeGestureRecognizer *recognizer;

recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self   
action:@selector(handleSwipeFrom:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionUp)];
recognizer.numberOfTouchesRequired = 2;
[[self view] addGestureRecognizer:recognizer];
[recognizer release];

// Delegate method
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {

    return YES;
}

// Helper method for handeling swipes
-(void)handleSwipeFrom:(UISwipeGestureRecognizer *)recognizer {
    if (recognizer.direction == UISwipeGestureRecognizerDirectionUp) {
        [self enableEditingMode];
    }
}

The painting mechanism is handled in the same controller's following methods:

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

It seems like the three methods above gets called before my UIGestureRecognizer. I have tried to make a BOOL variable, and disable the painting code if the boolean variable is YES. But this didn't work. Any other ideas on how to solve this problem would be great!

Note: I'm doing the swipe testing in the simulator. Maybe that effects it?

Anders
  • 2,903
  • 7
  • 58
  • 114

3 Answers3

1

You need to make sure that you also implement

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

In that you can then undo the touches.

hypercrypt
  • 15,389
  • 6
  • 48
  • 59
  • Hi, thanks. I'm pretty new with iOS development. Do you know if it's possible to use NSUndoManager in touchesCancelled? I tried it but I didn't get a grip of it. Or is there a better approach? Thinking of implementing the swiping feature in 1.1, it was tougher than I hoped. – Anders Oct 07 '11 at 09:18
  • How are you keeping track of the drawing? – hypercrypt Oct 07 '11 at 14:46
0

In my opinion, registering both the gesture recognizer & touches* methods is not a good idea. They are bound to interfere with each other. You should only register touches* methods, and determine whether it was a swipe. Don't draw if it was a swipe in the requisite direction.

Akshay
  • 5,747
  • 3
  • 23
  • 35
  • Hi, thanks for your answer. Does that mean that I have to implement custom gesture recognizers? Should be a simpler way, and I want my gestures to behave as they do in other apps. Or is it possible to use the "classic" gesture recognizers in my touches methods? Also, I tried delaysTouchesBegan but it made the app really sluggish. – Anders Oct 06 '11 at 16:55
  • Not really custom gesture recognizers, but detecting simple horizontal or vertical swipes is actually quite trivial. Have a look at http://www.dosomethinghere.com/2009/07/23/simple-swipe-detection-in-the-iphone-sdk/, http://stackoverflow.com/questions/2042930/successful-swipe-in-uitextview. I don't think it is possible to use the built-in gesture recognizers in your touches methods. – Akshay Oct 07 '11 at 10:18
  • Cool, will check that out later. However, on my quick skim through I couldn't find anything about two finger swipes. tapCount only detects taps, is there a counterpart for numberOfTouchesRequired = 2 (UIGestureRecognizer method) that I can use in my touch methods? Or is there another way to detect two finger swipes? Thanks. – Anders Oct 07 '11 at 11:28
-1

I might have got it to work. Have only tested it in the simulator yet though, unsure if it will work on a device since the simulator recognizes two finger touches instantly. The solution looks like this (as of http://www.iphonedevsdk.com/forum/iphone-sdk-development/23537-implemented-touchesbegan-only-giving-me-one-touch.html):

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

    NSSet *allTouches = [touches setByAddingObjectsFromSet:[event allTouches]];
    if (allTouches.count== 1) {
        if (isUsingPen) {
            [self painting:touches];
        }
        if (isUsingEraser) {
            [self erasing:touches];
        }  
    }
}

I will notify if this works on a device as well, or have anyone else tried this approach on a device?

Anders
  • 2,903
  • 7
  • 58
  • 114