Determining Location of A Long Press Gesture Recognizer

Go To StackoverFlow.com

4

Currently I have Long Pres Gesture Recognizers on four different TableViews (two in each storyboard scene, therefore two storyboard scenes). I create these LPGR's with the following code in my ViewDidLoad method...

//Add Long Press Gesture Reconizer
UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc] 
                                      initWithTarget:self action:@selector(handleLongPress:)];
lpgr.minimumPressDuration = 1; //seconds
lpgr.delegate = self;
[self.GolferOne addGestureRecognizer:lpgr];
[self.GolferTwo addGestureRecognizer:lpgr];
[self.GolferThree addGestureRecognizer:lpgr];
[self.GolferFour addGestureRecognizer:lpgr];
//Done Adding Long Press Gesture Reconizer

Next I have another method that I want to NSLog where the LPG was pressed...

CGPoint p = [gestureRecognizer locationInView:self.GolferOne];

   NSIndexPath *indexPath = [self.GolferOne indexPathForRowAtPoint:p];
    if (indexPath == nil)
        NSLog(@"long press on table view but not on a row [Golfer One]");
    else
        NSLog(@"long press on table view at row %d [Golfer One]", indexPath.row);

    //Golfer Two

    p = [gestureRecognizer locationInView:self.GolferTwo];

    indexPath = [self.GolferTwo indexPathForRowAtPoint:p];
    if (indexPath == nil)
        NSLog(@"long press on table view but not on a row [Golfer Two]");
    else
        NSLog(@"long press on table view at row %d [Golfer Two]", indexPath.row);

    //Golfer Three

    p = [gestureRecognizer locationInView:self.GolferThree];

    indexPath = [self.GolferThree indexPathForRowAtPoint:p];
    if (indexPath == nil)
        NSLog(@"long press on table view but not on a row [Golfer Three]");
    else
        NSLog(@"long press on table view at row %d [Golfer Three]", indexPath.row);

    //Golfer Four

    p = [gestureRecognizer locationInView:self.GolferFour];

    indexPath = [self.GolferFour indexPathForRowAtPoint:p];
    if (indexPath == nil)
        NSLog(@"long press on table view but not on a row [Golfer Four]");
    else
        NSLog(@"long press on table view at row %d [Golfer Four]", indexPath.row);

I know why it won't work, but I can't find a solution to get it to work. Instead of just returing one NSLog it returns something four times (once for each golfer because three of them have the indexPath=nil)

Any help will be appreciated. Also why is there such a lag for it to NSLog?

2012-04-05 01:57
by The Man


6

You can get the touch point of recognizer using ,

 -(void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer
{
 NSLog(@"%@",NSStringFromCGPoint([[gestureRecognizer valueForKey:@"_startPointScreen"] CGPointValue]));

}

you will get the point respect to the co-ordinate system of view for which your recognizer is added.

Your recognizer is registered only for the last Golfer. you should do this,

UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc] 
                                      initWithTarget:self action:@selector(handleLongPress:)];
lpgr.minimumPressDuration = 1; //seconds
[self.GolferOne addGestureRecognizer:lpgr];
[lgpr release];
lpgr = [[UILongPressGestureRecognizer alloc] 
                                      initWithTarget:self action:@selector(handleLongPress:)];
lpgr.minimumPressDuration = 1; //seconds

[self.GolferTwo addGestureRecognizer:lpgr];
[lgpr release];
2012-04-05 02:50
by Vignesh
But where, in the manual,"valueForKey" is explained for UIGestureRecognizer? - giuseppe 2013-08-01 13:34
valueForKey is KVC. KVC can be applied for any object which KVC compliant - Vignesh 2013-08-01 14:12
I know this old but for anyone who comes across this in the future. If you want to determine which row was long pressed you need to use CGPoint p = [gestureRecognizer locationInView:myTableView]; The value from the key _startPointScreen is offset and will return the wrong row when using NSIndexPath *indexPath = [myTableView indexPathForRowAtPoint:p] - Dave S 2014-07-16 21:21


6

To determine the location of the gesture in the view from the recognizer’s locationInView: property:

// Get the location of the gesture
CGPoint location = [recognizer locationInView:self.view];
2013-08-23 18:02
by polarwar
That's what I was looking for. Much better than KVC ;- - Katlu 2014-05-06 11:26


0

Long press recognizer is applied to the entire view. To have a 'lag' with NSLog you can just use NSTimer. A way you could get a result like your want is buttons with alpha of zero. When they release (be it 1 seconds or 120) it would log the touch.

2012-04-05 02:05
by Sirens


0

  1. As TheDeveloper said, the long press gesture is for the entire view.

  2. As an aside, if you were setting up gestures for multiple views, I believe that you want a separate gesturerecognizer for each view. Not relevant here, but I see lots of guys wondering why a gesture that they've tried to assign to multiple views is only working for one.

  3. With long press gestures, I'd suggest you check your sender.state == UIGestureRecognizerStateEnded or Started or whatever you're looking for. You're going to get multiple events triggered for one user interaction.

  4. If you've got the gesture on a view and you want to see, for example, if the user released their finger while over a particular subview, you can get the CGPoint for the release (via the locationInView, as Vignesh pointed out), you can then also get the CGRect for a particular subview's frame and then check to see if the CGPoint is inside the CGRect via CGRectContainsPoint().

2012-04-05 03:05
by Rob
Also Please note that you would get points with respect to their co-ordinate system. so CGRectContaintsPoint can be effectively used only after converting the co-ordinate system - Vignesh 2012-04-05 03:12
Ads