4
votes

I am having difficulty getting a UITapGestureRecognizer to detect every tap that is occurring. For context, I am making a drumming app. I have gotten the tap gesture recognizer to work correctly, but the user should be able to tap very quickly to drum, and the recognizer is only picking up on let's say a tap every so often (if you try to tap as quickly as you can).

I am guessing this has to do with iOS categorizing very quick taps in a row as one gesture, but is there any way to get every time a finger goes down as a tap event?

I have tried using UILongPressGestureRecognizer with a small press duration.

I have tried setting the requiredNumberofTouches and requiredNumberofTaps to 1.

The code does not seem necessary to post in order to answer the question, but I will post it if you request it.

Any help would be most appreciated!

EDIT: I am adding my code, since it may help:

-(void)tap:(UITapGestureRecognizer *)tapGestureRecognizer {

    CGPoint location = [tapGestureRecognizer locationInView:[self view]];

    switch ([self validateTouchLocation:location]) {
        case 0:
            return;
        case 1:
            [[ASSoundManager sharedManager] playSoundNamed:@"SD0025" ofType:@"mp3"];
            break;
        case 2:
        default:
            [[ASSoundManager sharedManager] playSoundNamed:@"SD0010" ofType:@"mp3"];
            break;
    }

    float tapWidth = 30;
    ASDrumTapView *drumTapView = [[ASDrumTapView alloc] initWithFrame:CGRectMake(location.x - (tapWidth / 2), location.y - (tapWidth / 2), tapWidth, tapWidth)];
    [drumTapView setBackgroundColor:[UIColor clearColor]];
    [drumTapView setNeedsDisplay];
    [[self view] addSubview:drumTapView];

    float animDuration = 0.75;
    CGRect frame = [drumTapView frame];

    [UIView animateKeyframesWithDuration:animDuration
                                   delay:0.0
                                 options:0
                              animations:^{
                                  [UIView addKeyframeWithRelativeStartTime:0
                                                          relativeDuration:animDuration
                                                                animations:^{
                                                                    [drumTapView setFrame:CGRectInset(frame, -frame.size.width, -frame.size.height)];
                                                                }];
                                  [UIView addKeyframeWithRelativeStartTime:0
                                                          relativeDuration:3*animDuration/5
                                                                animations:^{
                                                                    [[drumTapView layer] setOpacity:0.0];
                                                                }];
                              }
                              completion:^(BOOL finished) {
                                  [drumTapView removeFromSuperview];
                              }];
}
2
Do you try with uitapgesturerecognizer ?tuledev
Yes (as I stated in the first paragraph). I have tried UITapGestureRecognizer and UILongPressGestureRecognizer.Adam Suskin
Sorry, I missed it. Did you try with touches event: touchesBegan ...?tuledev
Yep. Same functionality. It works for taps in general, but if you try to tap really quickly in a row, it won't pick up on every tap.Adam Suskin
What did you do inside the gesture recognizer selector, looks like some time consuming stuff blocked the main threadEric Qian

2 Answers

3
votes

There could be many reason:

  • One possible reason could be fact that your audio engine cannot play next sound before previous sound has finished.
  • Check multipleTouchEnabled property on UIView
  • If your view is embedded in UIScrollView or any derived class, check delaysContentTouches property
1
votes

While I appreciate everyone's input, I figured it out on my own.

In my code, I am running a keyframe animation with options set to 0. What this means is that during the animation, user interaction with the view is not enabled.

By setting options to UIKeyframeAnimationOptionAllowUserInteraction, I am able to pick up on taps even though one of the subviews is still in animation.

Hope this helps someone else!