views:

59

answers:

4

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?

A: 

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;
  }
}
Tim Isganitis
A: 

@ 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.

Dave
A: 

@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.

Dave
Are you checking the pinch gesture recognizer's state? If there is a pinch gesture happening (that it has recognized), it has to be in either the Began or Changed states. Note that the gesture recognizer reference passed to the delegate method is whatever gesture recognizer that wants to begin precessing touches, not the pinch gesture recognizer. So, you need to save a reference to the pinch gesture recognizer and use that. See the code I've added to my original answer...
Tim Isganitis
A: 

@ 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.

Dave
Check out the Stack Overflow FAQ question "What is reputation?" In a nutshell, you earn reputation from other users by asking and answering good questions. At certain thresholds you earn privileges like editing and commenting. You've already earned some rep (the 13 next to your name) because someone "voted up" this question (the 1 next to your question).
Tim Isganitis
Actually, since you asked this question you should be able to comment on any of the answers with the "add a comment" link below each answer even though you don't have much rep. Generally that's how people respond to answers instead of making new answers like you did, but no worries...
Tim Isganitis