rudensm
rudensm

Reputation: 1474

Using UILongPressGestureRecognizer and UISwipeGestureRecognizer simultaneously

I create a simple view (black square) with long press gesture and drag it on the screen (UIGestureRecognizerStateChanged) until i catch UIGestureRecognizerStateEnded. OK, this works well. Now I want to be able to start recognizing additional gesture (UISwipeGestureRecognizer) for this black square view. The algorithm is simple:

  1. Create black square with long press
  2. Finger stays on screen
  3. Drag square view (setCenter:)
  4. Swipe and recognize UISwipeGestureRecognizer

The problem is that I cant recognize swipe while the long press gesture is not finished (UIGestureRecognizerStateEnded)

#pragma mark - View lifecycle

- (void)loadView {
    [super loadView];

    // Long press
    self.longPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(gestureAction:)];
    [self.longPressGestureRecognizer setDelegate:self];
    [self.view addGestureRecognizer:self.longPressGestureRecognizer];

    // Swipe
    self.swipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(gestureAction:)];
    [self.swipeGestureRecognizer setDelegate:self];
    [self.swipeGestureRecognizer setEnabled:NO];
    [self.view addGestureRecognizer:self.swipeGestureRecognizer];
}

#pragma mark - Gesture recognizer

- (void)gestureAction:(UIGestureRecognizer *)recognizer {

    // Swipe
    if ([recognizer isKindOfClass:NSClassFromString(@"UISwipeGestureRecognizer")]) {
        NSLog(@"swipeGestureRecognizer handled!!");
    }

    // Long press
    if ([recognizer isKindOfClass:NSClassFromString(@"UILongPressGestureRecognizer")]) {
        if (recognizer.state == UIGestureRecognizerStateBegan) {
            self.activeView = [[ItemView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
            [self.activeView setBackgroundColor:[UIColor blackColor]];
            self.activeView.center = [recognizer locationInView:self.view];
            [self.view addSubview:self.activeView];
        }
        else if (recognizer.state == UIGestureRecognizerStateChanged) {
            if (![self.swipeGestureRecognizer isEnabled]) {
                [self.swipeGestureRecognizer setEnabled:YES];
                NSLog(@"swipeGestureRecognizer enabled");
            }
            self.activeView.center = [recognizer locationInView:self.view];
        }
        else if (recognizer.state == UIGestureRecognizerStateEnded) {
            [self.swipeGestureRecognizer setEnabled:NO];
            NSLog(@"swipeGestureRecognizer disabled");
            [self.activeView removeFromSuperview];
            self.activeView = nil;
        }
    }
}

#pragma mark - UIGestureRecognizerDelegate

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    return YES;
}

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    return YES;
}

P.S. I want the behavior exactly as in native Calendar app when you are creating an event on the day canvas with long press. If you swipe an object (before you end long press gesture) it smoothly disappears.

Upvotes: 1

Views: 2272

Answers (2)

akshaynhegde
akshaynhegde

Reputation: 1938

For multiple gestures to recognized simultaneosly, you need to use the following delegate method from UiGestureRecognizer Protocol,

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;

Here is the LINK to the documentation.

EDIT

So I tried doing the same thing and, Yes even in my case the swipe was not recognized until long press is over..! So fi you want to move the view around, THen use PanGesture instead of swipe gesture..! It will work I just tried..:)

Upvotes: 1

YoYoHu
YoYoHu

Reputation: 92

You switch off the swipe recognizer with enabled:NO. I suggest to keep it on. And count for example the times one gesture is recognized. If the same gesture is received then dont add this counter. When it happens in the right order you set a function to do an action open/free.

Upvotes: 0

Related Questions