I'm currently having some conflicts with UIGestureRecognizers that is causing everything to place nice with each other. I have several squares (UIView) on the screen that let the user to pan and pinch (used to scale the views). I have a UIPinchGestureRecognizer added to the main view which the squares are added so that I can scale the square in focus. I've also added UIPanGestureRecognizers to each square so that it can be moved around in the screen. The problem manifests itself when I pinch to scale a selected square while my fingers are moving across the others. Based on my debugging, it appears that if my pinching fingers go across the non focused squares they eat the touches which cancel out the pinching gesture. Using "[pan requireGestureRecognizerToFail: pinch]" give the pinch priority but creates and issue because the continuous pan recognizer no longer fires. I've also tried to add the UIPinchRecognizer directly to the square but which works but the gesture has the constraint of being within the bounds of the square which does not work well if the square is scaled down too much. Is there a way around this? I'm I missing something?
One way around your problem would be to set a single common delegate for all of your UIGestureRecognizers (probably the UIViewController for this view). That delegate could return NO for gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer if the pinch gesture recognizer was in the "Began" or "Changed" states (meaning it was recognizing and processing a pinch). That should prevent any of the pan gesture recognizers from eating touches during a pinch gesture.
In the interface file, you will need to save a reference to the pinch gesture recognizer:
@interface MyViewController : UIViewController <UIGestureRecognizerDelegate> {
UIGestureRecognizer *pinchGestureRecognizer;
}
And in the implementation, make sure you check the pinch gesture recognizer's state, not the state of the gesture recognizer being passed:
@implementation MyViewController
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
if(pinchGestureRecognizer.state == UIGestureRecognizerStateBegan ||
pinchGestureRecognizer.state == UIGestureRecognizerStateChanged)
{
return NO;
}
else
{
return YES;
}
}
@ aBitOvious: Thanks, that sample code is actually pretty good. @ Tim: I'm not setting the delegate at all right now so I'll definitely look into that since it should allow be to control who eats what. I'll know more once I dig into the source.
@Tim: So I tried your suggestion and it did not help out. The gestuerRecognizer's state is always 0 and never switches to "Began" or "Changed". I guess the only way is to deal with the fact that the gesture recognizer needs to be added to the square and touch only be relevant to the square's bounds.
@ Tim: That worked great! I guess I got too many other scenarios running in my mind and that for some reason was not to clear to me but it totally makes sense. Thanks alot! BTW, how do you respond to answers or edit your posts? Do you have to be logged in? I'm just using name fields. Again thanks.