Custom gesture not sending action message - objective-c

I have created a UIGestureRecognizer subclass called LongPressGestureRecognizer to simulate a long press gesture. (Yes, I know about the concrete subclass which already exists, I'm just learning objective-c and experimenting a bit.)
I have overridden only the following methods :
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
self.state = UIGestureRecognizerStatePossible;
[self performSelector:#selector(setState:) withObject:[NSNumber numberWithInt:UIGestureRecognizerStateRecognized] afterDelay:2];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
[NSObject cancelPreviousPerformRequestsWithTarget:self];
self.state = UIGestureRecognizerStateCancelled;
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[NSObject cancelPreviousPerformRequestsWithTarget:self];
self.state = UIGestureRecognizerStateFailed;
}
and in my view controller with a property recognizer to store the gesture recogniser, i have the following code:
- (LongPressGestureRecognizer *)recognizer
{
if (!_recognizer) {
_recognizer = [[LongPressGestureRecognizer alloc] init];
}
return _recognizer;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self.recognizer addTarget:self action:#selector(log:)];
[self.view addGestureRecognizer:self.recognizer];
}
- (IBAction)log:(LongPressGestureRecognizer *)recognizer
{
//blah blah blah
}
My problem is that log: is not getting called at all... By logging the UIGestureRecogniserStates in the console, I know that the gesture recogniser is working as expected as far as states are concerned...
What am I doing wrong here?

There may be other issues as well, but I can tell you that your -performSelector:withObject:afterDelay: call isn't going to work the way you're hoping; you'll end up passing a pointer to an NSNumber object instead of an int, so state will be set to some kind of junk value. Create a method that will do self.state = UIGestureRecognizerStateRecognized and call that instead.

Related

NSUndoManager with TouchesEnded for MKPolyline

This is my first time trying to use NSUndoManager and i'm not sure where I should be putting it/what i'm missing. I'm making an application that has a map view with a draw button and undo button. I have the draw button enable the user to draw a polyline and every time their finger leaves the screen it connects another line to the line they just drew. I want the undo button to get rid of the last line that they drew.
some of what I have so far...
- (void)viewDidLoad
{
[super viewDidLoad];
...
...
undoManager = [[NSUndoManager alloc]init];
}
- (IBAction)oopsButton:(id)sender {
[undoManager undo];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
....
....
[[undoManager prepareWithInvocationTarget:self]touchesEnded:(touches) withEvent:event];
[undoManager setActionName:NSLocalizedString(#"Route Changed", #"route undo")];
}
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
...
...
right now, when I click undo, it undoes one line but that's all. I need it to keep undoing for as many times as the user clicks. Thanks for any help on this, i've been looking all over google and stack and haven't found anything that helps yet.
I found a way to update the polyline without using undo manager...
- (IBAction)oopsButton:(id)sender {
//remove last point from array
[self.coordinates removeLastObject];
//update line on map
NSInteger numberOfPoints = [self.coordinates count];
if (numberOfPoints > 1)
{
MKPolyline *oldPolyLine = self.polyLine;
CLLocationCoordinate2D points[numberOfPoints];
for (NSInteger i = 0; i < numberOfPoints; i++)
points[i] = [self.coordinates[i] MKCoordinateValue];
MKPolyline *newPolyLine = [MKPolyline polylineWithCoordinates:points count:numberOfPoints];
[self.mapView addOverlay:newPolyLine];
self.polyLine = newPolyLine;
if (oldPolyLine)
[self.mapView removeOverlay:oldPolyLine];
}
}

calling a method in IBAction method

Im trying to create a program that when i tap the screen, alert will popup..
So I change the UIView to UIControl, and create an IBAction method When tap the screen, Then i found a method on the internet the print the tap location.
this is my code:
-(IBAction) Touch:(id)sender{
[self touchesBegan];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *myTouch = [[touches allObjects] objectAtIndex: 0];
CGPoint currentPos = [myTouch locationInView: self];
NSLog(#"Point in myView: (%f,%f)", currentPos.x, currentPos.y);
}
and its give's me an error...
What to do?!?!
remove [self touchesBegan] from your "Touch" method
you are
1. calling this method without the necessary parameters, so you are
probably getting unrecognized selector sent to instance,
2. the uiview calls this method on its own, you just need to override it

Subclass of GestureRecognizer does not work

I am trying to subclass gesture recognizer to detect touch down , and not touch up .
The subclassing is working , only when i don't put this row to enable scrolling :
[touchDown requireGestureRecognizerToFail:scroller.panGestureRecognizer];
the subclass implementation :
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if (self.state == UIGestureRecognizerStatePossible)
{
self.state = UIGestureRecognizerStateRecognized;
}
}
problem is , that i need that row ,otherwise the scroller will not move..
implementation :
TouchDownGestureRecognizer *touchDown = [[TouchDownGestureRecognizer alloc] initWithTarget:self action:#selector(handleTouchDown:)];
[scroller addGestureRecognizer:touchDown];
[touchDown requireGestureRecognizerToFail:scroller.panGestureRecognizer];//not work with it.
solution to enable scroller :
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}

Why won't my Cocos2d test app fire "touchesBegan" events?

In my app delegate, I made sure I have the line:
[glView setMultipleTouchEnabled: YES];
And I have a simple layer meant only to figure out how multi touch works. The .mm file looks like:
#import "TestLayer.h"
#implementation TestLayer
-(id) init
{
if( (self=[super init])) {
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];
}
return self;
}
-(void) draw{
[super draw];
glColor4f(1.0, 0.0, 0.0, 0.35);
glLineWidth(6.0f);
ccDrawCircle(ccp(500,500), 250,CC_DEGREES_TO_RADIANS(360), 60,YES);
}
-(void) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"got some touches");
}
-(void) ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"some touches moved.");
}
-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
NSLog(#"a touch began");
return FALSE;
}
#end
When I touch the screen, I always see "a touch began", but no matter how I touch it (simulator or actual device), I never see "some touches moved" or "got some touches".
Is there something further I need to do to make multi touch work?
Specifically, I'm just trying to do basic pinch-to-zoom functionality... I heard there is some sort of gesture recognizer for iPhone...does it work for Coco2ds? Would it work even if I can't get simple multi touch events to fire?
UIGestureRecognizers absolutely work for Cocos2D, I personally used them, you just need to add them to the correct view by using:
[[[CCDirector sharedDirector] openGLView] addGestureRecognizer:myGestureRecognizer];
Regarding your touches, I guess you enabled them for the scene you are working in?
scene.isTouchEnabled = YES;
In any case you shouldn't use the addTargetDelegate method, take a look here
add self.isTouchEnabled = YES; to your init
and for the gesture recognizers look at the other answer

ccTouchesBegan vs ccTouchBegan - Touch Detection & SIGABRT crash

I'm currently doing an application where I'm trying to detect touch-positions of the user.
I changed from ccTouchBegan to ccTouchesBegan in the process of implementing the "detect touch-position" function.
But I can't get it to work. I changed from ccTouchBegan to ccTouchesBegan:
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
instead of using:
-(BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event{
When i did this the whole thing crashes when I click the screen. Generating a SIGABRT error higlighting:
#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
NSAssert(NO, #"Layer#ccTouchBegan override me");
return YES;
}
#endif
#end
So my questions are:
Why do you think it crashes?
What's the difference between ccTouchBegan & ccTouchesBegan? Multi touch abilities?
For further help, this is my code:
-(id) init
{
if( (self=[super init])) {
[CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGBA8888];
self.isTouchEnabled = YES;
// Set up background
background = [CCSprite spriteWithFile:#"Image.png"];
background.scaleX = 1;
background.scaleY = 1;
background.position = ccp(0,0);
[self addChild:background];
[[CCTouchDispatcher sharedDispatcher]addTargetedDelegate:self
priority:0
swallowsTouches:YES];
// Preload sound effect
soundFile = [SimpleAudioEngine sharedEngine];
if (soundFile != nil) {
[soundFile preloadBackgroundMusic:#"sound.wav"];
}
}
return self;
}
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
NSLog(#"ccTouchesBegan");
// Sets the sound variable to YES
ifOne = YES;
prevPos = [touch locationInView:[touch self]];
prevPos = [[CCDirector sharedDirector] convertToGL:[touch locationInView:touch.self]];
[self schedule:#selector(timerUpdate:) interval:0.1];
//return YES;
}
It's a nice feature in cocos2d which lets you swallow touches in cases that you want to handle only a single touch event.
Try adding this function to your class:
- (void) registerWithTouchDispatcher {
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:INT_MIN+1 swallowsTouches:YES];
}
ccTouchesBegan happens the second you tap the screen
ccTouchesEnded happens the second you let go after tapping on the screen
and instead of
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
instead of using:
-(BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event{
try using
-(void)ccTouchesBegan:(UITouch *)...
or
-(void)ccTouchesBegan:(NSSet *)...
or
-(BOOL)ccTouchesBegan:(NSSet *)...
your problem may just be invalid data types or some crap like that, my advice is just try switching the types of touches around.
I would give more info but you didn't provide alot of information to work with, so this is the best I can do.