0

I have a UIScrollView. I put a tap gesture to it as this:

self.tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.tapped(_:)))
self.tapGesture.delegate = self
self.tapGesture.numberOfTapsRequired = 1
self.tapGesture.numberOfTouchesRequired = 1
self.tapGesture.cancelsTouchesInView = false
self.tapGesture.delaysTouchesBegan = false
self.tapGesture.delaysTouchesEnded = false
self.scrollView.addGestureRecognizer(self.tapGesture)

This works fine, except when the scrollview is scrolling (scrolling animation is happening, not user dragging), tap gesture is ignored.

How I am animating the scroll view:

UIView.animate(withDuration: 0.3, delay: 0.0,
                           options:[.beginFromCurrentState, .curveEaseInOut], animations:
    {
        self.scrollView.contentOffset = CGPoint(x:self.scrollView.contentOffset.x, y:yOffset)
    },  completion: nil)

This scrollview is scrolling most the time and I am trying to get it to recognize the tap gesture while scroll view is animating scrolling ....

Gizmodo
  • 3,151
  • 7
  • 45
  • 92

1 Answers1

2

Take a look at the UIGestureRecogniserDelegate functions.

You should be able to specify that both the pan and tap gestures can be recognised at the same time with the following function:

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, 
shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return (gestureRecogniser is UIPanGestureRecogniser || gestureRecogniser is UITapGestureRecogniser) && (otherGestureRecognizer is UIPanGestureRecogniser || otherGestureRecognizer is UITapGestureRecogniser) 
}

Note: Ensure your class conforms to the UIGestureRecogniserDelegate protocol and you set the gestures delegate so self.

This should work, but I am unable to fully test it right now.

UPDATE:

If you are trying to recognise a tap during an animation you will likely need to use the UIViewAnimationOptions.AllowUserInteraction option in the options of UIView.animateWithDuration. Used this other answer as a source

Scriptable
  • 19,402
  • 5
  • 56
  • 72
  • I already had shouldRecognizeSimultaneouslyWith method in, but returned true all times. So according to that, tap should have been recognized while scrolling? – Gizmodo Jun 13 '17 at 19:28
  • 1
    In theory yes, it should work. Maybe the delegate for the scrollView is setup differently. let me try to replicate the issue and come back to you – Scriptable Jun 13 '17 at 19:33
  • I think u are focusing on a pan gesture from scrollview. I apologize, I corrected OP above. The issue is, when the scrolling animation happens, not when the user dragging.... – Gizmodo Jun 13 '17 at 19:44
  • 1
    Ok, I see. what are you trying to get from the tap? – Scriptable Jun 13 '17 at 19:46
  • when tapped I want to get in to func tapped () method. This gets called fine when scroll view is static. It's ignored when scrolling animation is happening.... – Gizmodo Jun 13 '17 at 19:48
  • 1
    anytime I tap when its animating.. the animation stops and tap is called. See this [Gist](https://gist.github.com/martinjkelly/9177d75c00f7b59d770cdecfbd7fa6d3) of a single view controller in a test project. (you may need to add an image and change the name) – Scriptable Jun 13 '17 at 20:01
  • Interesting. I am using self.scrollView.contentOffset = .... wrapped around a UIView animation for the scrolling animation. Wonder if that has anything to do with it.... – Gizmodo Jun 13 '17 at 20:05
  • That would likely be the cause yes, as the animation will more than likely take priority. That would of been useful to know at the start :( we keep getting little bits of more information that changes the possible solutions – Scriptable Jun 13 '17 at 20:07
  • Solution? https://stackoverflow.com/questions/13686429/uitapgesturerecognizer-not-work-when-i-animate-the-uiimageview. I think this should solve your problem. I've added it to the answer too for anybody else reading this post. – Scriptable Jun 13 '17 at 20:08
  • WOW! .allowUserInteraction worked! Could you please type this in a reply so I can give it "Answered" mark? – Gizmodo Jun 13 '17 at 20:11
  • I've put it in the answer above :) – Scriptable Jun 13 '17 at 23:48