Search code examples
iosobjective-cuigesturerecognizertouchesbegan

Issues using touchesBegins


I have a button. I want to change the image on initial touch. If the touch is less then 1 seconds, I want it to do X. If the touch is longer then 1 second, I want it to do Y.

I'm having trouble figuring out how to handle this. A UIButton has proved troublesome so I thought I could do it with UIGestureRecognizers or touchesBegin:

Initial thought was have a UITapGestureRecognizer to detected just a quick tap to do X, and use a UILongTapGestureRecognizer to handle a longer press to do Y.

The issue is a UITapGestureRecognizer does not flag UIGestureRecognizerStateBegan, it only ever sends a notice for UIGestureRecognizerStateEnd.

So I decided trying a combination of overridding the touchesBegin: and touchesEnd: methods and using a UILongPressGestureRecognizer:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    // change image
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    // do X
    // change image to original image
}

-(IBAction)longPressDetected:(UILongPressGestureRecognizer *)recognizer {
    DLog(@"fired");

    if (recognizer.state == UIGestureRecognizerStateBegan) {
        // Do y
        // change image to original image
    }
    else if (recognizer.state == UIGestureRecognizerStateCancelled) {

    }
    else if (recognizer.state == UIGestureRecognizerStateEnded) {

    }
}

If the UILongPressGestureRecognzier fires, it cancels the inital touchesBegan: (does not fire touchesEnded: method).

But I have run into the issue where the touchesBegin: method is slow to fire. There is a .5 second delay in the method being fired. What baffles me, if I use UILongPressGestureRecognizer with a longTap.minimumPressDuration = 0, it fires instantly.

This is with in the program where I need it to be. Playing around with it in a dummy area, the touchesBegins: fires instantly as well.

What could cause it to lag within the program?

Is there a different way I can obtain the desired effect?


Solution

  • maybe you could use a timer and a Long Press Gesture Recognizer

    UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(didRecognizeLongPressGesture:)];
    longPress.minimumPressDuration = 0;
    [self.button addGestureRecognizer:longPress];
    

    ...

    - (void)didRecognizeLongPressGesture:(UILongPressGestureRecognizer*)gesture
    {
        static NSTimer *timer = nil;
    
        if (gesture.state == UIGestureRecognizerStateBegan)
        {
            timer = [NSTimer scheduledTimerWithTimeInterval:1.1 target:self selector:@selector(changeImage:) userInfo:nil repeats:NO];
            //change the image here
        }
        else if ( gesture.state == UIGestureRecognizerStateEnded)
        {
            if ([timer isValid])
            {
                //the user has pressed the button less than a second
                [timer invalidate];
                timer = nil;
            }
    
        }
    
    }
    
    - (void)changeImage:(NSTimer*)timer
    {
        [timer invalidate];
        timer = nil;
    
        //change to the other image here
    }