Custom UIGestureRecognizer: selector does not receive UIGestureRecognizerStateBegan

I am implementing custom UIGestureRecognizer. For simplicity, let assume that it recognizes gesture that consists of >1 touches.

Here is Gesture.m:

#import "Gesture.h"
#import <UIKit/UIGestureRecognizerSubclass.h>

#define SHOW printf("%s %d %d %d\n", __FUNCTION__, self.state, touches.count, self.numberOfTouches)

@implementation Gesture

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
  SHOW;
  if (self.numberOfTouches==1) return;
  self.state = UIGestureRecognizerStateBegan;
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
  SHOW;
  if (self.numberOfTouches==1) return;
  self.state = UIGestureRecognizerStateChanged;
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
  SHOW;
  if (self.numberOfTouches==1) return;
  self.state = UIGestureRecognizerStateEnded;
}
@end

Here is a selector:

- (IBAction)handleGesture:(Gesture *)recognizer {
  printf("%s %d\n", __FUNCTION__, recognizer.state);
}

And here is an output:

-[Gesture touchesBegan:withEvent:] 0 1 1  // 1st touch began
-[Gesture touchesMoved:withEvent:] 0 1 1
-[Gesture touchesMoved:withEvent:] 0 1 1
-[Gesture touchesMoved:withEvent:] 0 1 1
-[Gesture touchesBegan:withEvent:] 0 1 2  // 2nd touch began
-[Gesture touchesMoved:withEvent:] 1 1 2  // Gesture.state==UIGestureRecognizerStateBegan but selector was not called
-[ViewController handleGesture:] 2        // UIGestureRecognizerStateChanged received.
-[Gesture touchesMoved:withEvent:] 2 2 2
-[ViewController handleGesture:] 2
-[Gesture touchesMoved:withEvent:] 2 2 2
-[ViewController handleGesture:] 2
-[Gesture touchesMoved:withEvent:] 2 2 2
-[ViewController handleGesture:] 3        // UIGestureRecognizerStateEnded received.

Why doesn't selector receive UIGestureRecognizerStateBegan?

Answers


It wasn't particularly obvious to me but the rules seem to be:

  • all touches sent to you via touchesBegan:... are subsequently considered to belong to you unless and until you set the state to UIGestureRecognizerStateFailed, UIGestureRecognizerStateEnded or UIGestureRecognizerStateCancelled;
  • if instead you transition to UIGestureRecognizerStateBegan then the gesture recogniser will post that on, then automatically generate UIGestureRecognizerStateChanged when the touches that are now assigned to you move.

So you're not supposed to set UIGestureRecognizerStateChanged for yourself — just keep track of the touches and correctly post began, ended, failed and cancelled.

In your case I think you just need to remove the state set within touchesMoved:....

(aside: the above is true of iOS 5 and 6; under 4 the behaviour is slightly more subtle. To work under all three versions use a construction like if(self.state == UIGestureRecognizerStateBegan) self.state = UIGestureRecognizerStateChanged; when you know that your properties have changed)


Need Your Help

Getting count of empty object on two different servers are different..!

php object count server

I am getting count of empty object as a '0' on local server and count of same empty obejct as a '1' on different server using PHP.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.