2

Setup: I have a Scroll View that works great horizontally as well as a UISwipeGestureRecognizer that triggers a segue to another view when I swipe down.

Problem: If I am scrolling horizontally and I begin to swipe down (vertical scrolling disabled) WHILE the scrolling is decelerating, the swipe down action (segue) does not execute. It only works once the scrolling deceleration is complete.

enter image description here

Is there a way to disable the scroll deceleration (aka inertia) so that my swipe down gesture can be detected instantly? Perhaps there's a workaround to force UISwipeGestureRecognizer to be detected first?

Solutions in Swift are highly appreciated!

Linus Juhlin
  • 1,175
  • 10
  • 31
theflarenet
  • 642
  • 2
  • 13
  • 27

3 Answers3

1

did you look here? Deactivate UIScrollView decelerating

the answer

-(void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView{  
[scrollView setContentOffset:scrollView.contentOffset animated:YES];   
}

converted to swift is

func scrollViewWillBeginDecelerating(scrollView: UIScrollView) {
scrollView.setContentOffset(scrollView.contentOffset, animated: true)
}
Community
  • 1
  • 1
RubberDucky4444
  • 2,330
  • 5
  • 38
  • 70
  • Unfortunately, I have tried that solution a few minutes ago and found that it interferes with my `UISwipeGestureRecognizer` swipe down detection. None of my gestures are detected once I use the scrollview due to that hack in the BeginDecelerating. Perhaps another hack in EndDecelerating as a workaround? – theflarenet May 22 '16 at 04:21
1

Swift 3:

To disable decelerating scroll you can try:

func scrollViewWillEndDragging (scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
    targetContentOffset.memory = scrollView.contentOffset
}

or you change this value:

scrollView.decelerationRate = UIScrollViewDecelerationRateNormal
// UIScrollViewDecelerationRateFast is the other param

About your gestureRecognizer interferences you can call this method to exclude touching from:

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
    // insert here views to exclude from gesture
    if touch.view!.isDescendantOfView(self.excludeThisView) {
        return false
    }
    return true
}
Alessandro Ornano
  • 34,887
  • 11
  • 106
  • 133
  • I did not know about `scrollViewWillEndDragging` and it looks very interesting. I tried it with `targetContentOffset.memory = scrollView.contentOffset` and it had no effect. For some reason, my `gestureRecognizer` is still delayed by the deceleration (or any bounce) in my scrollView. My goal is to allow `gestureRecognizer` to execute instantly without being delayed by any scrolling deceleration. – theflarenet Jun 09 '16 at 21:50
  • targetContentOffset is now a let var. cannot be mutated – Return-1 Oct 03 '17 at 14:22
1

UIScrollView has a pinchGestureRecognizer and a panGestureRecognizer.If you have a UISwipeGestureRecognizer,the gesture will most likely be recognized as a UIPanGestureRecognizer.
You can add a dependence to solve the problem:

scrollView.panGestureRecognizer.requireGestureRecognizerToFail(swipeGesture)
wj2061
  • 6,778
  • 3
  • 36
  • 62