How to add a push pin to a MKMapView(IOS) when touching? - iphone

I had to get the coordinate of a point where the user touch on a MKMapView.
I'm not working with the Interface Builder.
Can you give me one example?

You can use a UILongPressGestureRecognizer for this. Wherever you create or initialize the mapview, first attach the recognizer to it:
UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:#selector(handleLongPress:)];
lpgr.minimumPressDuration = 2.0; //user needs to press for 2 seconds
[self.mapView addGestureRecognizer:lpgr];
[lpgr release];
Then in the gesture handler:
- (void)handleLongPress:(UIGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer.state != UIGestureRecognizerStateBegan)
return;
CGPoint touchPoint = [gestureRecognizer locationInView:self.mapView];
CLLocationCoordinate2D touchMapCoordinate =
[self.mapView convertPoint:touchPoint toCoordinateFromView:self.mapView];
YourMKAnnotationClass *annot = [[YourMKAnnotationClass alloc] init];
annot.coordinate = touchMapCoordinate;
[self.mapView addAnnotation:annot];
[annot release];
}
YourMKAnnotationClass is a class you define that conforms to the MKAnnotation protocol. If your app will only be running on iOS 4.0 or later, you can use the pre-defined MKPointAnnotation class instead.
For examples on creating your own MKAnnotation class, see the sample app MapCallouts.

Thanks to Anna for providing such a great answer! Here is a Swift version if anybody is interested (the answer has been updated to Swift 4.1 syntax).
Creating UILongPressGestureRecognizer:
let longPressRecogniser = UILongPressGestureRecognizer(target: self, action: #selector(MapViewController.handleLongPress(_:)))
longPressRecogniser.minimumPressDuration = 1.0
mapView.addGestureRecognizer(longPressRecogniser)
Handling the gesture:
#objc func handleLongPress(_ gestureRecognizer : UIGestureRecognizer){
if gestureRecognizer.state != .began { return }
let touchPoint = gestureRecognizer.location(in: mapView)
let touchMapCoordinate = mapView.convert(touchPoint, toCoordinateFrom: mapView)
let album = Album(coordinate: touchMapCoordinate, context: sharedContext)
mapView.addAnnotation(album)
}

Related

handle taps in two different points at a same time via UIGestureRecognizer

I have two labels in two different positions, when both labels are tapped at the same time i want another label to show a success message.
How do I accomplish this? I can recognize a single tap or double tap with one or more finger touches but this is a different scenario. Please help. I tried this, but it does not work.
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTap:)];
tapRecognizer.numberOfTapsRequired = 1;
tapRecognizer.numberOfTouchesRequired = 2;
tapRecognizer.delegate = self;
[self.view addGestureRecognizer:tapRecognizer];
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if (touch.view == tap2 && touch.view == tap1)
{
result.text = #"success";
}
return YES;
}
Thanks in advance.
What you're trying to detect isn't really a single gesture.
I'd suggest adding a tap gesture recogniser to each button. The handler would:
Store the time of the tap (at the moment that the handler is called)
Compare this time with the time that the other button was last
tapped. If the times are very similar (perhaps 0.25 secs apart),
consider that they've both been tapped simultaneously and react
accordingly.
Play with the time interval on a real device to find the ideal amount.
UPDATE:
A code snippet that obviously hasn't been tested in any way:
- (void)handleButton1Tap:(UITapGestureRecognizer *)sender {
if (sender.state == UIGestureRecognizerStateEnded)
{
self.button1TapTime = CACurrentMediaTime();
[self testForSimultaneousTap];
}
}
- (void)handleButton2Tap:(UITapGestureRecognizer *)sender {
if (sender.state == UIGestureRecognizerStateEnded)
{
self.button2TapTime = CACurrentMediaTime();
[self testForSimultaneousTap];
}
}
- (void)testForSimultaneousTap
{
if (fabs(self.button1TapTime - self.button2TapTime) <= 0.2)
{
// Do stuff
}
}
where self.button1TapTime and self.button2TapTime are member variables (doubles).
Tim
Formally I had accepted termes's answer first and that worked too, but I have found a more simpler solution to this process. There is no need for two gesture recognizers, it is achievable with a simple tap gesture recognizer with number of touches count to two. Here is the code:
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTap:)];
tapRecognizer.numberOfTapsRequired = 1;
tapRecognizer.numberOfTouchesRequired = 2;
tapRecognizer.delegate = self;
[self addGestureRecognizer:tapRecognizer];
Now, in the handle tap method we can easily get the two touch points by "locationOfTouch:inView:", a instance method of UIGestureRecognizer class. So in the handleTap: method we need to check if the two touch points are in the desired location. Here is the code:
-(void)handleTap:(UITapGestureRecognizer*)recognizer
{
if (recognizer.state == UIGestureRecognizerStateEnded)
{
CGPoint point1 = [recognizer locationOfTouch:0 self];
CGPoint point2 = [recognizer locationOfTouch:1 self];
if ([self validateTapIn:point1 and:point2])
{
resultLabel.text = #"success";
}
}
}
-(BOOL)validateTapIn:(CGPoint)point1 and:(CGPoint)point2
{
return
(CGRectContainsPoint(label1.frame, point1) && CGRectContainsPoint(label2.frame,:point2)) ||
(CGRectContainsPoint(label1.frame, point2) && CGRectContainsPoint(label2.frame, point1));
}

Selecting Location from MapView

I was thinking of an application where user could select a location on an iphone app. I have googled it and didn't find anything useful.
My question is, is it possible to let the user select a location from an iphone app using MapKit/CLLocation? If yes, please help me where should i start.
Thanks
You can add a long press gesture recognizer to the map:
UILongPressGestureRecognizer* lpgr = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(handleLongPress:)];
lpgr.minimumPressDuration = 1.5;
lpgr.delegate = self;
[self.map addGestureRecognizer:lpgr];
[lpgr release];
In the handle long press method get the CLLocationCordinate2D:
- (void) handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer {
if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
/*
Only handle state as the touches began
set the location of the annotation
*/
CLLocationCoordinate2D coordinate = [self.map convertPoint:[gestureRecognizer locationInView:self.map] toCoordinateFromView:self.map];
[self.map setCenterCoordinate:coordinate animated:YES];
// Do anything else with the coordinate as you see fit in your application
}
}
Take a look at this SO answer. The answer tells you not only how to get the coordinate, but also how to put a pin (annotation) on the map.

How to recognize swipe in all 4 directions?

I need to recognize swipes in all directions (Up/Down/Left/Right). Not simultaneously, but I need to recognize them.
I tried:
UISwipeGestureRecognizer *Swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(SwipeRecognizer:)];
Swipe.direction = (UISwipeGestureRecognizerDirectionLeft |
UISwipeGestureRecognizerDirectionRight |
UISwipeGestureRecognizerDirectionDown |
UISwipeGestureRecognizerDirectionUp);
[self.view addGestureRecognizer:Swipe];
[Swipe release];
but nothing appeared on SwipeRecognizer
Here's the code for SwipeRecognizer:
- (void) SwipeRecognizer:(UISwipeGestureRecognizer *)sender {
if ( sender.direction == UISwipeGestureRecognizerDirectionLeft )
NSLog(#" *** SWIPE LEFT ***");
if ( sender.direction == UISwipeGestureRecognizerDirectionRight )
NSLog(#" *** SWIPE RIGHT ***");
if ( sender.direction == UISwipeGestureRecognizerDirectionDown )
NSLog(#" *** SWIPE DOWN ***");
if ( sender.direction == UISwipeGestureRecognizerDirectionUp )
NSLog(#" *** SWIPE UP ***");
}
How can I do this? How can assign to my Swipe object all different directions?
You set the direction like this
UISwipeGestureRecognizer *Swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(SwipeRecognizer:)];
Swipe.direction = (UISwipeGestureRecognizerDirectionLeft |
UISwipeGestureRecognizerDirectionRight |
UISwipeGestureRecognizerDirectionDown |
UISwipeGestureRecognizerDirectionUp);
That's what the direction will be when you get the callback, so it is normal that all your tests fails. If you had
- (void) SwipeRecognizer:(UISwipeGestureRecognizer *)sender {
if ( sender.direction | UISwipeGestureRecognizerDirectionLeft )
NSLog(#" *** SWIPE LEFT ***");
if ( sender.direction | UISwipeGestureRecognizerDirectionRight )
NSLog(#" *** SWIPE RIGHT ***");
if ( sender.direction | UISwipeGestureRecognizerDirectionDown )
NSLog(#" *** SWIPE DOWN ***");
if ( sender.direction | UISwipeGestureRecognizerDirectionUp )
NSLog(#" *** SWIPE UP ***");
}
The tests would succeed (but the would all succeed so you wouldn't get any information out of them). If you want to distinguish between swipes in different directions you will need separate gesture recognizers.
EDIT
As pointed out in the comments, see this answer. Apparently even this doesn't work. You should create swipe with only one direction to make your life easier.
Unfortunately you cannot use direction property for listening the recognizer; it only gives you the detected directions by the recognizer. I have used two different UISwipeGestureRecognizers for that purpose, see my answer here: https://stackoverflow.com/a/16810160/936957
I actually ran into this exact problem before. What I ended up doing was creating a UIView subclass, overriding touchesMoved: and doing some math to calculate the direction.
Here's the general idea:
#import "OmnidirectionalControl.h"
typedef NS_ENUM(NSInteger, direction) {
Down = 0, DownRight = 1,
Right = 2, UpRight = 3,
Up = 4, UpLeft = 5,
Left = 6, DownLeft = 7
};
#interface OmnidirectionalControl ()
#property (nonatomic) CGPoint startTouch;
#property (nonatomic) CGPoint endTouch;
#end
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
self.startTouch = [[touches allObjects][0] locationInView:self];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
self.lastTouch = [[[touches allObjects] lastObject] locationInView:self];
NSLog(#"Direction: %d", [self calculateDirectionFromTouches]);
}
-(direction)calculateDirectionFromTouches {
NSInteger xDisplacement = self.lastTouch.x-self.startTouch.x;
NSInteger yDisplacement = self.lastTouch.y-self.startTouch.y;
float angle = atan2(xDisplacement, yDisplacement);
int octant = (int)(round(8 * angle / (2 * M_PI) + 8)) % 8;
return (direction) octant;
}
For simplicity's sake in touchesMoved:, I only log the direction, but you can do what you want with that information (e.g. pass it to a delegate, post a notification with it, etc.). In touchesMoved you'll also need some method to recognize if the swipe is finished or not, but that's not quite relevant to the question so I'll leave that to you. The math in calculateDirectionFromTouches is explained here.
I finally found the simplest answer, please mark this as the answer if you agree.
If you only have one direction swipe + pan, you just say:
[myPanRecogznier requireGestureRecognizerToFail:mySwipeRecognizer];
But if you have two or more swipes, you can't pass an array into that method. For that, there's UIGestureRecognizerDelegate that you need to implement.
For example, if you want to recognize 2 swipes (left and right) and you also want to allow the user to pan up, you define the gesture recognizers as properties or instance variables, and then you set your VC as the delegate on the pan gesture recognizer:
_swipeLeft = [[UISwipeGestureRecognizer alloc] ...]; // use proper init here
_swipeRight = [[UISwipeGestureRecognizer alloc] ...]; // user proper init here
_swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
_swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
_pan = [[UIPanGestureRecognizer alloc] ...]; // use proper init here
_pan.delegate = self;
// then add recognizers to your view
You then implement - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer delegate method, like so:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
if (gestureRecognizer == _pan && (otherGestureRecognizer == _swipeLeft || otherGestureRecognizer == _swipeRight)) {
return YES;
}
return NO;
}
This tells the pan gesture recognizer to only work if both left and right swipes fail to be recognize - perfect!
Hopefully in the future Apple will just let us pass an array to the requireGestureRecognizerToFail: method.
Use a UIPanGestureRecogizer and detect the swipe directions you care about. see the UIPanGestureRecognizer documentation for details. -rrh
// add pan recognizer to the view when initialized
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(panRecognized:)];
[panRecognizer setDelegate:self];
[self addGestureRecognizer:panRecognizer]; // add to the view you want to detect swipe on
-(void)panRecognized:(UIPanGestureRecognizer *)sender
{
if (sender.state == UIGestureRecognizerStateBegan) {
// you might want to do something at the start of the pan
}
CGPoint distance = [sender translationInView:self]; // get distance of pan/swipe in the view in which the gesture recognizer was added
CGPoint velocity = [sender velocityInView:self]; // get velocity of pan/swipe in the view in which the gesture recognizer was added
float usersSwipeSpeed = abs(velocity.x); // use this if you need to move an object at a speed that matches the users swipe speed
NSLog(#"swipe speed:%f", usersSwipeSpeed);
if (sender.state == UIGestureRecognizerStateEnded) {
[sender cancelsTouchesInView]; // you may or may not need this - check documentation if unsure
if (distance.x > 0) { // right
NSLog(#"user swiped right");
} else if (distance.x < 0) { //left
NSLog(#"user swiped left");
}
if (distance.y > 0) { // down
NSLog(#"user swiped down");
} else if (distance.y < 0) { //up
NSLog(#"user swiped up");
}
// Note: if you don't want both axis directions to be triggered (i.e. up and right) you can add a tolerence instead of checking the distance against 0 you could check for greater and less than 50 or 100, etc.
}
}
CHANHE IN STATEEND CODE WIH THIS
//if YOU WANT ONLY SINGLE SWIPE FROM UP,DOWN,LEFT AND RIGHT
if (sender.state == UIGestureRecognizerStateEnded) {
[sender cancelsTouchesInView]; // you may or may not need this - check documentation if unsure
if (distance.x > 0 && abs(distance.x)>abs(distance.y)) { // right
NSLog(#"user swiped right");
} else if (distance.x < 0 && abs(distance.x)>abs(distance.y)) { //left
NSLog(#"user swiped left");
}
if (distance.y > 0 && abs(distance.y)>abs(distance.x)) { // down
NSLog(#"user swiped down");
} else if (distance.y < 0 && abs(distance.y)>abs(distance.x)) { //up
NSLog(#"user swiped up");
}
}
You can add only one diagonal by SwipeGesture, then...
UISwipeGestureRecognizer *swipeV = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(action)];
UISwipeGestureRecognizer *swipeH = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(action)];
swipeH.direction = ( UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionRight );
swipeV.direction = ( UISwipeGestureRecognizerDirectionUp | UISwipeGestureRecognizerDirectionDown );
[self addGestureRecognizer:swipeH];
[self addGestureRecognizer:swipeV];
self.userInteractionEnabled = YES;
UISwipeGestureRecognizer *Updown=[[UISwipeGestureRecognizer alloc]initWithTarget:self action:#selector(handleGestureNext:)];
Updown.delegate=self;
[Updown setDirection:UISwipeGestureRecognizerDirectionDown | UISwipeGestureRecognizerDirectionUp];
[overLayView addGestureRecognizer:Updown];
UISwipeGestureRecognizer *LeftRight=[[UISwipeGestureRecognizer alloc]initWithTarget:self action:#selector(handleGestureNext:)];
LeftRight.delegate=self;
[LeftRight setDirection:UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionRight];
[overLayView addGestureRecognizer:LeftRight];
overLayView.userInteractionEnabled=NO;
-(void)handleGestureNext:(UISwipeGestureRecognizer *)recognizer
{
NSLog(#"Swipe Recevied");
}
It might not be the best solution but you can always specify different UISwipeGestureRecognizer for each swipe direction you want to detect.
In the viewDidLoad method just define the required UISwipeGestureRecognizer:
- (void)viewDidLoad{
UISwipeGestureRecognizer *recognizerUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeUp:)];
recognizerUp.direction = UISwipeGestureRecognizerDirectionUp;
[[self view] addGestureRecognizer:recognizerUp];
UISwipeGestureRecognizer *recognizerDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeDown:)];
recognizerDown.direction = UISwipeGestureRecognizerDirectionDown;
[[self view] addGestureRecognizer:recognizerDown];
}
Then just implement the respective methods to handle the swipes:
- (void)handleSwipeUp:(UISwipeGestureRecognizer *)sender{
if (sender.state == UIGestureRecognizerStateEnded){
NSLog(#"SWIPE UP");
}
}
- (void)handleSwipeDown:(UISwipeGestureRecognizer *)sender{
if (sender.state == UIGestureRecognizerStateEnded){
NSLog(#"SWIPE DOWN");
}
}

App crashing when I add overlay to mkmapview

I am trying to add annotations and overlays to a mapview but it crashes randomly. It is an EXC_BAD_ACCESS error, but zombies doesn't tell me anything. It says it is crashing on CG::Path::apply_transform(CGAffineTransform const&). I have looked everywhere for why this is happening but can't pinpoint it.
I am creating the mapview in ib and have the delegates and everything set up right. It will work sometimes and then crash randomly.
I am using a gesture recognizer to add the annotations and overlay
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(handleDoubleTap:)];
[doubleTap setNumberOfTapsRequired:2];
[self.mapView addGestureRecognizer:doubleTap];
and
- (void)handleDoubleTap:(UIGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer.state == UIGestureRecognizerStateRecognized){
CGPoint touchPoint = [gestureRecognizer locationInView:self.mapView];
CLLocationCoordinate2D touchMapCoordinate =
[self.mapView convertPoint:touchPoint toCoordinateFromView:self.mapView];
//add pin where user touched down...
MKPointAnnotation *pa = [[MKPointAnnotation alloc] init];
pa.coordinate = touchMapCoordinate;
//[pa setTitle:#"title"];
[mapView addAnnotation:pa];
MKCircle* circle=[MKCircle circleWithCenterCoordinate:touchMapCoordinate radius:500];
[mapView addOverlay:circle];
}
}
And the views for each:
-(MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id)overlay
{
if ([overlay isKindOfClass:[MKCircle class]]) {
MKCircleView* circleView = [[MKCircleView alloc] initWithOverlay:overlay];
circleView.strokeColor = [UIColor redColor];
circleView.lineWidth = 1.0;
circleView.fillColor = [UIColor blackColor];
circleView.alpha=.5;
return circleView;
}
else
return nil;
}
- (MKAnnotationView *)mapView:(MKMapView *)localmapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if (![annotation isKindOfClass:[MKUserLocation class]]) {
static NSString *AnnotationIdentifier = #"Annotation";
MKPinAnnotationView* pinView = (MKPinAnnotationView *)[localmapView dequeueReusableAnnotationViewWithIdentifier:AnnotationIdentifier];
if (!pinView)
{
pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationIdentifier];
pinView.pinColor = MKPinAnnotationColorRed;
pinView.animatesDrop = YES;
}
else
{
pinView.annotation = annotation;
}
return pinView;
}
return nil;
}
Is there a better way to add annotations/overlays to maps with user interaction? Am I doing something wrong in this code? It appears to draw most of the circle but then crashes... Is there some special trick to mapviews?
I've been getting the exact same error:
CG::Path::apply_transform(CGAffineTransform const&) will hit a test instruction and give me an EXC_BAD_ACCESS
This specifically occurs when using a double click on the map to zoom in on an MKCircle.
I can't say this definitively, but to the best of my knowledge this problem only occurs on the simulator when you use a double click to zoom, I've never been able to cause the error from an actual device, or by using option+click to zoom on the simulator.
So at this point I've filed this under "simulator bug" and left it at that.
If you do discover anything to the contrary, please let me know because it really bothers me not explicitly knowing whether or not this is a bug existing in my app that I just can't properly reproduce.
edit:
This was flagged initially as "not an answer" so I'll provide a little bit more information supporting my conjecture.
Basically in both of our scenarios a gesture is firing the re-rendering of the MKCircleView, what I strongly suspect is that since the simulator is able to generate some kind of gesture which can't be created from a user on the actual device, there is a failed expectation somewhere down the chain while that gesture gets handled.
I am not sure where your EXC_BAD_ACCESS problems is. But you have a big problem with leaking memory. You have to releas object that you create with init. In the above code you create objects and never release them. That will not throw EXC_BAD_ACCESS but it will consume your memory.
Release the following object :
MKPointAnnotation *pa = [[MKPointAnnotation alloc] init];
MKCircleView* circleView = [[MKCircleView alloc] initWithOverlay:overlay];

cocos2d-iOS - Gesture recognisers

Has anyone managed to get the gesture recognition working in cocos-2d?
I have read a post here that claimed to have achieved it, here: http://www.cocos2d-iphone.org/forum/topic/8929
I patched from the git hub here: https://github.com/xemus/cocos2d-GestureRecognizers/blob/master/README
I made a subclass of CCSprite (which is a subclass of CCNode):
-(id) initWithTexture:(CCTexture2D*)texture rect:(CGRect)rect {
if( (self=[super initWithTexture:texture rect:rect]) )
{
CCGestureRecognizer* recognizer;
recognizer = [CCGestureRecognizer
CCRecognizerWithRecognizerTargetAction:[[[UITapGestureRecognizer alloc]init] autorelease]
target:self
action:#selector(tap:node:)];
[self addGestureRecognizer:recognizer];
}
return self;
}
Delegate method:
- (void) swipe:(UIGestureRecognizer*)recognizer node:(CCNode*)node
{
NSLog(#" I never get called :( ");
}
My tap event never gets called.
Has anyone got this working? How difficult is it to do gesture recognition manually for swipe detection?
You need to attach the gesture recognizer to something "up the chain". Don't attach them to the individual nodes; attach them to the UIView (i.e., [[CCDirector sharedDirector] openGLView]).
Here's what I did:
- (UIPanGestureRecognizer *)watchForPan:(SEL)selector number:(int)tapsRequired {
UIPanGestureRecognizer *recognizer = [[[UIPanGestureRecognizer alloc] initWithTarget:self action:selector] autorelease];
recognizer.minimumNumberOfTouches = tapsRequired;
[[[CCDirector sharedDirector] openGLView] addGestureRecognizer:recognizer];
return recognizer;
}
- (void)unwatch:(UIGestureRecognizer *)gr {
[[[CCDirector sharedDirector] openGLView] removeGestureRecognizer:gr];
}
This particular code is used in a superclass for scene controllers, so the target for the selector is hard-coded to "self", but you could easily abstract that to a passed-in object. Also, you could extrapolate the above to easily create gesture recognizers for taps, pinches, etc.
In the subclass for the controller, then, I just do this:
- (MyController *)init {
if ((self = [super init])) {
[self watchForPan:#selector(panning:) number:1];
}
return self;
}
- (void)panning:(UIPanGestureRecognizer *)recognizer {
CGPoint p;
CGPoint v;
switch( recognizer.state ) {
case UIGestureRecognizerStatePossible:
case UIGestureRecognizerStateBegan:
p = [recognizer locationInView:[CCDirector sharedDirector].openGLView];
(do something when the pan begins)
break;
case UIGestureRecognizerStateChanged:
p = [recognizer locationInView:[CCDirector sharedDirector].openGLView];
(do something while the pan is in progress)
break;
case UIGestureRecognizerStateFailed:
break;
case UIGestureRecognizerStateEnded:
case UIGestureRecognizerStateCancelled:
(do something when the pan ends)
(the below gets the velocity; good for letting player "fling" things)
v = [recognizer velocityInView:[CCDirector sharedDirector].openGLView];
break;
}
}
If you don't want to handle everything manually I created a simple category that will add gesture recognizers to any cocos2d version
read more at:
http://www.merowing.info/2012/03/using-gesturerecognizers-in-cocos2d/
or grab it from github
https://github.com/krzysztofzablocki/CCNode-SFGestureRecognizers