Cosmin
Cosmin

Reputation: 2908

Count number of taps with UITapGestureRecognizer

I have a button that increases a quantity, and when I tap it, I make a service call. The problem is that if I tap it multiple times I only want to make the service call after I finish tapping it. I tried using a UITapGestureRecognizer but I don't know how to count the number of taps.

Any help would be appreciated.

Here is the sample code

- (void)quantityChanged:(UITapGestureRecognizer *)tapRecognizer {
    static NSUInteger numberOfTaps;
    if (tapRecognizer.state == UIGestureRecognizerStateBegan) {
       numberOfTaps = 0;
    }
    if (tapRecognizer.state == UIGestureRecognizerStateEnded)
        NSLog(@"%d",numberOfTaps);
    if (tapRecognizer.state == UIGestureRecognizerStateChanged)
        numberOfTaps++;

}

Upvotes: 0

Views: 5619

Answers (4)

Pau Ballada
Pau Ballada

Reputation: 1628

Without a UITapGestureOrganizer it's even easier.

button.addTarget(self, action: #selector(multipleTap(_:event:)), for: UIControlEvents.touchDownRepeat)

And then:

func multipleTap(_ sender: UIButton, event: UIEvent) {
    let touch: UITouch = event.allTouches!.first!
    if touch.tapCount == 3 {
        print("triple tap")
    }
}

Upvotes: 0

Kai Huppmann
Kai Huppmann

Reputation: 10775

Even though I doubt that this will lead to a practical user interface ... If you have an idea of a maximum count the user can "put in", you could go with several tap gesture listeners which you make dependent of each other with - (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer (doc here).

The code could look like this:

-(void)addGestureRecognizers
{
  int maxCount = 10;
  UITapGestureRecognizer *other = nil;
  for(int i = maxCount; i < 0; i--)
  {
    UITapGestureRecognizer *tapper = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapped:)];
    tapper.numberOfTapsRequired = i;
    if(other)
    {
      [tapper requireGestureRecognizerToFail:other]; 
    }
    [self.view addGestureRecognizer:tapper];
    other = tapper;
  }
}

-(void)tapped:(UITapGestureRecognizer *)tapper
{
  [self callWebservice:tapper.numberOfTapsRequired];
}

I didn't test it, never worked with that, but that's what I understood from the docs.

Upvotes: 1

Shamsudheen TK
Shamsudheen TK

Reputation: 31311

Four possible solutions

I think Your method is fine

- (void)quantityChanged:(UITapGestureRecognizer *)tapRecognizer {

    static NSUInteger numberOfTaps;


   if (tapRecognizer.state == UIGestureRecognizerStateEnded) {

        numberOfTaps ++;

        NSLog(@"web service call with %d",numberOfTaps);
    }

}

see the log

web service call with 1
web service call with 2
web service call with 3
web service call with 4

or

Remove the quantityChanged UITapGestureRecognizer after triggered it one's

I mean , remove the UITapGestureRecognizer from the sender object (inside the quantityChanged method after your first web-service)

Then Add UITapGestureRecognizer to the sender again after u got the first web-service response.

or

Use UILongPressGestureRecognizer . It's is a long event process. Please check the event state either its started,completed etc and write your code.

- (IBAction)longPressDetected:(UIGestureRecognizer *)gestureRecognizer {        

    if (gestureRecognizer.state == UIGestureRecognizerStateBegan){

        NSLog(@"Long press began");

    } else if ( gestureRecognizer.state == UIGestureRecognizerStateRecognized ) {

            NSLog(@"Long press UIGestureRecognizerStateRecognized");
    }
    else if (gestureRecognizer.state == UIGestureRecognizerStateEnded) {

        NSLog(@"Long press Ended");
    }
    else {

        NSLog(@"Long press detected.");
    }       
}

or

Set the numberOfTapsRequired for UITapGestureRecognizer

UITapGestureRecognizer *doubleTapRecognizer = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(beginComicTransitions:)] autorelease];    
doubleTapRecognizer.numberOfTapsRequired = 2;
doubleTapRecognizer.numberOfTouchesRequired = 1;
doubleTapRecognizer.delegate = self;

Upvotes: 4

Cosmin
Cosmin

Reputation: 2908

Ok. So I found the solution to my problem. I will perform my web service call with a delay of 0.5 seconds, and each time I press on my button I cancel all the selectors that are waiting to be performed and a call again performSelector: withDelay.

Upvotes: 0

Related Questions