filtering single and double taps
Asked Answered
W

4

19

When the user single taps my view, i need one specific method to run. When the user double taps, i need another method do take place.

The problem is that the double tap triggers the single tap, and it introduce bugs in my logic. I can't use UIGestureRecognizer because i need to keep track of the points.

I try some booleans, but no chance. I also tried the cancel/perfomSelector-delay technique, but it does not work (that's strange because other folks on other forums said it works, maybe the simulator touch detection is different ?)

I'm trying to let the user set the position (drag, rotate) of a board piece, but i need to be aware of piece intersections, clip to the board area, etc, that's why a simple boolean will not solve the problem.

Thanks in advance!

Wieche answered 5/7, 2011 at 18:53 Comment(1)
Should post your code for the cancel/perfomSelector-delay, as that works fine.Abacist
H
45

Check this, seems right what you are looking for:

Below the code to use UITapGestureRecognizer to handle single tap and double tap. The code is designed that it won't fire single tap event if we got double tap event. The trick is use requireGestureRecognizerToFail to ask the single tap gesture wait for double tap event failed before it fire. So when the user tap on the screen, the single tap gesture recognizer will not fire the event until the double tap gesture recognizer. If the double tap gesture recognizer recognize the event, it will fire a double tab event and skip the single tap event, otherwise it will fire a single tap event.

    UITapGestureRecognizer *doubleTapGestureRecognizer = [[UITapGestureRecognizer alloc]
                            initWithTarget:self action:@selector(handleDoubleTap:)];
    doubleTapGestureRecognizer.numberOfTapsRequired = 2;

    //tapGestureRecognizer.delegate = self;
    [self addGestureRecognizer:doubleTapGestureRecognizer];

    //
    UITapGestureRecognizer *singleTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
    singleTapGestureRecognizer.numberOfTapsRequired = 1;

    [singleTapGestureRecognizer requireGestureRecognizerToFail: doubleTapGestureRecognizer];
    //tapGestureRecognizer.delegate = self;
    [self addGestureRecognizer:singleTapGestureRecognizer];

Possibly I don't understand exactly what you mean by "i need to keep track of the points", but I don't see any problems with doing this with a gesture recognizer.

Hell answered 5/7, 2011 at 18:58 Comment(1)
Thank you very much, that works but i find another problem...I have a CGPoint instance variable, that keep track of the drag start point (set in touchesBegan). If the user drag the piece to a incorrect place(like on the top of another piece), i set the piece position to that start point, in touchesEnded. But if the user rotates the piece, and set an incorrect place, my start point will be replaced by the touch point, and i'll not be able to 'reset' the piece to the start point...i'm confused to implement this simple rotate/drop piece positioning!Wieche
T
7

Swift 3 Solution:

doubleTap = UITapGestureRecognizer(target: self, action:#selector(self.doubleTapAction(_:)))
doubleTap.numberOfTapsRequired = 2


singleTap = UITapGestureRecognizer(target: self, action:#selector(self.singleTapAction(_:)))
singleTap.numberOfTapsRequired = 1

singleTap.require(toFail: doubleTap)

self.view.addGestureRecognizer(doubletap)
self.view.addGestureRecognizer(singleTap)

In the code line singleTap.require(toFail: doubleTap) we are forcing the single tap to wait and ensure that the tap even is not a double tap. Which means we are asking to ensure the double tap event has failed hence it is concluded as a single tap.

Thundershower answered 27/10, 2016 at 13:8 Comment(0)
P
1

Swift Solution :

    doubleTapSmall1.numberOfTapsRequired = 2
    doubleTapSmall1.addTarget(self, action: "doubleTapPic1")
    smallProfilePic1.addGestureRecognizer(doubleTapSmall1)

    singleTapSmall1.numberOfTapsRequired = 1
    singleTapSmall1.addTarget(self, action: "singleTapPic1")
    singleTapSmall1.requireGestureRecognizerToFail(doubleTapSmall1)
    smallProfilePic1.addGestureRecognizer(singleTapSmall1)
Prism answered 10/9, 2015 at 10:12 Comment(0)
S
0

Just implement the UIGestureRecognizer delegate methods by setting the delegate properly.

 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
            return  YES;
        }

    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
        return YES;
    }

Also add this line of code

[singleTap requireGestureRecognizerToFail:doubleTap];
Sweetbread answered 10/5, 2017 at 13:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.