Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UILongPressGestureRecognizer will not respond to touch & HOLD

I am writing an Objective-C program for iPhone.

I am trying to implement a UILongPressGestureRecognizer and cannot get it to behave the way I want it to.

What I want to do is simple:

Respond to a touch being held down on the screen.

The UILongPressGestureRecognizer works just fine whenever the touch moves and when the touch begins but if I hold down the touch in the same place, nothing happens.

Why?

How can I handle a touch begining, not moving, and staying in the exact same place?

Here's my current code.


// Configure the press and hold gesture recognizer 
touchAndHoldRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(touchAndHold:)]; 
touchAndHoldRecognizer.minimumPressDuration = 0.1; 
touchAndHoldRecognizer.allowableMovement = 600;
[self.view addGestureRecognizer:touchAndHoldRecognizer];
like image 920
J-Rock Avatar asked Feb 01 '13 01:02

J-Rock


1 Answers

The behavior you describe, where your gesture recognizer does not receive further calls to your handler when you're not moving is the standard behavior. The state property for these gestures as you move are of type UIGestureRecognizerStateChanged, so it makes sense that if things haven't changed, your handler won't be called.

You could

  • Upon call to your gesture recognizer with state of UIGestureRecognizerStateBegan start a repeating timer;
  • Upon call to your gesture recognizer with state of UIGestureRecognizerStateCancelled, UIGestureRecognizerStateFailed, or UIGestureRecognizerStateEnded then invalidate and release the timer;
  • Make sure the gesture recognizer method is saving whatever value you're looking for in some class property (e.g. the value of locationInView or whatever)

So, maybe something like:

@interface ViewController ()

@property (nonatomic) CGPoint location;
@property (nonatomic, strong) NSTimer *timer;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    UILongPressGestureRecognizer *gesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
    gesture.minimumPressDuration = 0.1;
    gesture.allowableMovement = 600;
    [self.view addGestureRecognizer:gesture];
}

- (void)handleTimer:(NSTimer *)timer
{
    [self someMethod:self.location];
}

- (void)handleGesture:(UIGestureRecognizer *)gesture
{
    self.location = [gesture locationInView:self.view];

    if (gesture.state == UIGestureRecognizerStateBegan)
    {
        self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(handleTimer:) userInfo:nil repeats:YES];
    }
    else if (gesture.state == UIGestureRecognizerStateCancelled ||
             gesture.state == UIGestureRecognizerStateFailed ||
             gesture.state == UIGestureRecognizerStateEnded)
    {
        [self.timer invalidate];
        self.timer = nil;
    }

    [self someMethod:self.location];
}

- (void)someMethod:(CGPoint)location
{
    // move whatever you wanted to do in the gesture handler here.

    NSLog(@"%s", __FUNCTION__);
}

@end
like image 89
Rob Avatar answered Nov 08 '22 02:11

Rob