Gesture problem: UISwipeGestureRecognizer + UISlider
Asked Answered
C

3

26

Got a gesture related problem. I implemented UISwipeGestureRecognizer to get swipe left and right events and that is working fine. However the problem I'm facing is that the UISlider's I have in the same view are not playing nice. The sliding motion of the sliders is being mistaken as a swipe left/right.

Any one experienced this problem before, got any ideas how to correct it?

Many thanks.

Here is the code contained within the view controller:

 - (void)viewDidLoad {

            [super viewDidLoad];

                //Setup handling of LEFT and RIGHT swipes
             UISwipeGestureRecognizer *recognizer;

                recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeFrom:)];
                [recognizer setDirection:(UISwipeGestureRecognizerDirectionRight)];
                [[self view] addGestureRecognizer:recognizer];
                [recognizer release];

                recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeFrom:)];
                [recognizer setDirection:(UISwipeGestureRecognizerDirectionLeft)];
                [[self view] addGestureRecognizer:recognizer];
                [recognizer release];
        }

    -(void)handleSwipeFrom:(UISwipeGestureRecognizer *)recognizer {

      if (recognizer.direction == UISwipeGestureRecognizerDirectionRight) {
       NSLog(@"Swipe Right");
       //Do stuff
      }

      if (recognizer.direction == UISwipeGestureRecognizerDirectionLeft) {
       NSLog(@"Swipe Left");
       //Do stuff
      }
    }
Cacomistle answered 22/1, 2011 at 1:57 Comment(0)
U
58

The simplest way to handle this is probably to prevent the gesture recognizer from seeing touches on your slider. You can do that by setting yourself as the delegate, and then implementing

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    if ([touch.view isKindOfClass:[UISlider class]]) {
        // prevent recognizing touches on the slider
        return NO;
    }
    return YES;
}

If this doesn't work, it's possible the slider actually has subviews that receive the touch, so you could walk up the superview chain, testing each view along the way.

Undershirt answered 22/1, 2011 at 3:40 Comment(5)
KEY POINT: You can do that by setting yourself as the delegate, and then implementing - this would be something like [panRecognizer setDelegate:self] - NOT the UISlider (depending on your naming & class setup, etc). Also, awesome answer.Democratize
Incomplete answer that also is buggy. Do not use.Strafe
@AlexKornhauser Please elaborate.Undershirt
Does not specify how to use the delegate.Strafe
@AlexKornhauser "How do I use a gesture recognizer delegate?" is not the point of this question. That's something that's answered by the documentation. Please do not declare answers to be "buggy" because they assume you already know the basics that the official documentation explains.Undershirt
P
3

Swift 4.0 version. Don't forget the UIGestureRecognizerDelegate.

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {

    if let touchedView = touch.view, touchedView.isKind(of: UISlider.self) {
        return false
    }

    return true
}
Pentyl answered 9/1, 2019 at 13:40 Comment(0)
C
0

I ended up getting this working just before Lily responded above. Here is the code I used, but Lily's looks cleaner (haven't tested Lily's thou):

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    BOOL AllowSwipes = YES;

        CGPoint point1 = [touch locationInView:_sliderLeft];
        CGPoint point2 = [touch locationInView:_sliderRight];

        //Left slider test
        if ([_sliderLeft hitTest:point1 withEvent:nil] != nil) {
            AllowSwipes = NO;
            NSLog(@"On Left Slider");
        }

        //Right slider test
        if ([_sliderRight hitTest:point2 withEvent:nil] != nil) {
            AllowSwipes = NO;
            NSLog(@"On Right Slider");
        }
    }
    return AllowSwipes;
}
Cacomistle answered 22/1, 2011 at 15:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.