简体   繁体   中英

How to have a UIScrollView scroll and have a gesture recognizer?

I have a gesture recognizer on a UIScrollView, however it hardly ever gets called as the UIScrollView eats all the gestures.

I partially got around this issue with this line: [scrollView.panGestureRecognizer requireGestureRecognizerToFail:rightSwipe]; however, this line results in my recognizer always being accepted (the desired behavior) and the scroll view not scrolling.

That is, when you scroll, the recognizer is accepted but the view doesn't scroll.

How can I get around this, or is there an alternate solution?

Thanks

Make a subclass of UIScrollView . Add this method in your new subclass

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

Make your scrollView class to your new scrollview subclass.

The way that works for me is subclass UIScrollView and conform to the UIGestureRecognizerDelegate in that subclass. Then call this method.

class ATScrollView: UIScrollView, UIGestureRecognizerDelegate { 
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,
                           shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    } 
}

Don't forget to assign proper delegation to your gesture recognizer mechanism:

So, for example:

Set a .up direction gesture recognizer

let swipeUp = UISwipeGestureRecognizer(target: self, action: #selector(self.handleGesture(gesture:)))
        swipeUp.direction = .up
        swipeUp.delegate = self // set delegate
        self.addGestureRecognizer(swipeUp)

Set a .down direction gesture recognizer

let swipeDown = UISwipeGestureRecognizer(target: self, action: #selector(self.handleGesture(gesture:)))
        swipeDown.direction = .down
        swipeDown.delegate = self // set delegate
        self.addGestureRecognizer(swipeDown)

Also don't forget to conform to delegation:

YourViewController: UIGestureRecognizerDelegate

Set simultaneous recognition:

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }

Then move on to your logic...

Hope it helps!

Swift method,
Need to add UIGestureRecognizerDelegate to your class:

class ViewController: UIViewController, UIGestureRecognizerDelegate {

Need to set its delegate to self:

override func viewDidLoad() {
    super.viewDidLoad()
    var scrollView = UIScrollView(frame: self.view.frame)
    scrollView.delegate = self
}

Add this part in your class methods to active simultaneous gestures:

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}

Forgive me for this tangent but I'm posting this answer just in case anyone else makes the same misdiagnosis I did. If like me the above solutions aren't working for you, make sure you're not trying to attach your UISwipeGestureRecognizer to more than one view. It can only work with one view, and that will be view to which it was most recently attached!

Rather than trying to work with TWO pan gestures (UIScrollView uses one internally already), just hijack the scrollview's built in pan gesture recognizer to make a second callback to your custom method as well.

After you set up yourScrollView, add this:

[yourScrollView.panGestureRecognizer addTarget:self action:@selector(scrollViewPan:)];

Then capture the scrollview's built in pan with the selector:

-(void)scrollViewPan:(UIPanGestureRecognizer *)sender {
    
    CGPoint translatedPoint = [sender translationInView:sender.view.superview];
    NSLog(@"%f,\t%f", translatedPoint.x, translatedPoint.y);
    
}

Make sure, of course, you have <UIGestureRecognizerDelegate> set in your.h

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM