Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent UIScrollView's UIPanGestureRecognizer from blocking UIScreenEdgePanGestureRecognizer

I have a UIScrollView that fills the screen on one page of my app, but I want to allow the user to pan from the edge of the screen to reveal a view behind it. The problem is that the UIScrollView steals the touches from my UIScreenEdgePanGestureRecognizer at the edge of the screen. Unfortunately, I can't access the UIScreenEdgePanGestureRecognizer from the view controller that has the UIScrollView (and vice-versa), so I am not able to use the method requireGestureRecognizerToFail: because I cannot able to specify which gesture recognizer should be allowed to fail. The view controller with the scroll view is a child view controller of a container view controller that has the screen edge pan gesture recognizer attached to one of the container view controller's own views.

I'm also unable to use the delegate method

-(BOOL)gestureRecognizer:shouldRequireFailureOfGestureRecognizer:

because the UIScrollView won't allow me to set my view controller as the delegate of the scroll view's UIPanGestureRecognizer.

How can I prevent the scrollview from stealing the edge pan touches from my own gesture recognizer?

like image 652
Tyler Cloutier Avatar asked Feb 15 '14 07:02

Tyler Cloutier


2 Answers

Unfortunately, creating this behavior can be a real P*** i* t** A**.

Fortunately, creating this behavior is possible using the UIGestureRecognizer Delegate even if you can't access one GestureRecognizer directly.

-(BOOL)gestureRecognizer:shouldRequireFailureOfGestureRecognizer:
-(BOOL)gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:
-(BOOL)gestureRecognizer:shouldBeRequiredToFailByGestureRecognizer: 

The second parameter ('otherGestureRecognizer') passed in the delegate methods holds the UIScrollView's PanGestureRecognizer (or private Apple - subclasses) when your gestureRecognizer 'collides' with the scrollView's.

So simply set your UIScreenEdgePanGestureRecognizer's delegate to reply to the delegate methods.

The naming of these two methods is very suboptimal and to be honest, i don't really know what the correct return values for your case are.

I just had this problem yesterday and i solved it by brutal trial & error.

Im my case, returning NO from both shouldRequireToFail and shouldBeRequiredToFail methods and YES from the simultaneous-method solved my problem.

Note: Returning NO from both methods changed the behavior compared to not 
even implementing the methods at all. Even though the documentation says 
the default return value is NO.

However, ANY GestureRecognizer behavior can be achieved by using the delegate methods. But as i said above, the naming of the methods is just very confusing. + there is as much as NO useful documentation for these methods.

like image 166
CodingMeSwiftly Avatar answered Nov 14 '22 19:11

CodingMeSwiftly


This can be done without having to set the screen pan gesture's delegate to your view controller.

[scrollView.panGestureRecognizer requireGestureRecognizerToFail:screenPanGesture];
like image 27
kevinnguy Avatar answered Nov 14 '22 20:11

kevinnguy