Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enable UIPanGestureRecognizer when did longPress

I'd like to enable UIPanGestureRecognizer on customView when the customView did longPress.
(I wish when you longPress customView, the customView will switch to "move mode", and you can move the customView by drag.)

But in this code, only longPressAction: called. panAction: did not called.
How do I fix it to enable PanAction:?

- (void)viewDidLoad
{
    [self.view addSubview:customView];

    UILongPressGestureRecognizer *longPressRecognizer = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPressAction:)];
    [customView addGestureRecognizer:longPressRecognizer];
    UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panAction:)];
    [customView addGestureRecognizer:panRecognizer];
}

- (void)longPressAction:(UILongPressGestureRecognizer *)recognizer
{
    if ([recognizer state] == UIGestureRecognizerStateBegan) {
        CustomView *customView = (CustomView *)recognizer.view;
        customView.panRecongnizerEnabled = YES; //panRecongnizerEnabled is CustomView's property
    }
    if ([recognizer state] == UIGestureRecognizerStateEnded) {
        CustomView *customView = (CustomView *)recognizer.view;
        customView.panRecongnizerEnabled = NO;
    }
}

- (void)panAction:(UIPanGestureRecognizer *)recognizer
{
    CustomView *customView = (CustomView *)recognizer.view;
    if (customCell.panRecongnizerEnabled == NO) return;
    NSLog(@"running panAction");
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}
like image 289
kusumoto_teruya Avatar asked May 03 '15 14:05

kusumoto_teruya


People also ask

What is UIPanGestureRecognizer?

UIPanGestureRecognizer is a concrete subclass of UIGestureRecognizer . Clients of this class can, in their action methods, query the UIPanGestureRecognizer object for the current translation of the gesture ( translation(in:) ) and the velocity of the translation ( velocity(in:) ).

What is a panning gesture?

A pan gesture occurs any time a person moves one or more fingers around the screen. A screen-edge pan gesture is a specialized pan gesture that originates from the edge of the screen.


2 Answers

Your ViewController needs to conform to the UIGestureRecognizerDelegate. I suspect you either already did that or otherwise the shouldRecognizeSimultaneouslyWithGestureRecognizer would not make any sense. But what you are definitely missing is setting the gestureRecognizer´s delegate to your viewController:

longPressRecognizer.delegate = self;
panRecognizer.delegate = self;

Now you should be receiving both long press and pan simultaneous.

Note: I tested without any customView, just added them to self.view. At least in that case, the code above worked as expected.

like image 195
luk2302 Avatar answered Sep 20 '22 00:09

luk2302


I know this question has been closed for a while, but I recently had to do something similar, and there is a much cleaner solution. The UILongPressGestureRecognizer is all you need to do this.

Long-press gestures are continuous. The gesture begins (UIGestureRecognizerStateBegan) when the number of allowable fingers (numberOfTouchesRequired) have been pressed for the specified period (minimumPressDuration) and the touches do not move beyond the allowable range of movement (allowableMovement). The gesture recognizer transitions to the Change state whenever a finger moves, and it ends (UIGestureRecognizerStateEnded) when any of the fingers are lifted.

Because of this, for what you need, there is no need for the UIPanGestureRecognizer. Simply add the UILongPressGestureRecognizer and attach it to your main view.

- (void)viewDidLoad {
    [super viewDidLoad];

    UILongPressGestureRecognizer *longPressRecognizer = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPressAction:)];
    // set this to your desired delay before the pan action will start.
    longPressRecognizer.minimumPressDuration = 0.5; 
    [self.view addGestureRecognizer:longPressRecognizer];
}

Then, implement the longPressAction method to look at not just UIGestureRecognizerStateBegan or UIGestureRecognizerStateEnded states, but also the UIGestureRecognizerStateChanged state:

- (void)longPressAction:(UIGestureRecognizer *)recognizer
{
    if ([recognizer state] == UIGestureRecognizerStateBegan || [recognizer state] == UIGestureRecognizerStateChanged ) {
        CGPoint touchPoint =  [recognizer locationInView:self.view];
        [self.viewToMove setCenter: touchPoint];
        NSLog(@"running panAction");
    }
}

In my example, I simply move a dummy view to track the center of the user's finger, but you can put any logic you would have put in the UIPanGestureRecognizer's code. Simply put it inside the if block and it greatly simplifies your code and you don't need to deal with interactions between the two gesture recognizers. Your code would also result in many needless calls to the panAction method when the user is simply moving their finger around the screen (but hasn't done a long press).

like image 33
wottle Avatar answered Sep 18 '22 00:09

wottle