0

I'm trying to implement a method that gets called in the touchesBegan method when I tap the screen. How do I add a delay so the method increment has a downtime of 2 seconds before it can be called again?

int i;
-(void)increment
{
     i++;
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
/* Called when a touch begins */
for (UITouch *touch in touches) {

    CGPoint location = [touch locationInNode:self];
    [self increment];
    }
}
CodeSmile
  • 64,284
  • 20
  • 132
  • 217
user2995344
  • 268
  • 1
  • 3
  • 14
  • 1
    What are you trying to achieve with this code? Maybe using one of `UIGestureRecognizer` subclasses would work better. – Michał Ciuba Jan 23 '15 at 22:24
  • @MichałCiuba Agreed. And if you specified `delegate` for your gesture recognizer, you could implement a `gestureRecognizerShouldBegin` that checked whether the allotted time had passed or not. – Rob Jan 23 '15 at 22:34
  • run an action sequence which has a wait (2 seconds) and runBlock action with the touch and block methods toggling a Bool class property that determines whether the method can fire again or not. – CodeSmile Jan 24 '15 at 10:09

4 Answers4

3

One way to do this is to enhance your increment method to perform its regular functionality only if the 2 seconds have elapsed, which is verified using a bool variable.

Example:

BOOL incrementMethodLocked = NO;

-(void)increment
{

     if(incrementMethodLocked)
     return;

     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{

          incrementMethodLocked = NO; // unlocks method for future use
     });

     i++;
     incrementMethodLocked = YES; // locks method
}
Vinod Vishwanath
  • 5,821
  • 2
  • 26
  • 40
  • 3
    I can't believe how often I need to say this: in Sprite Kit, do not use dispatch, performSelector or NSTimer for timed events. In this instance if the game had a "pause" menu, the user might enter pause menu after touching, wait 2 seconds, resume the game and can tap again since there's no way to pause dispatch_after. See: http://stackoverflow.com/a/23978854/201863 – CodeSmile Jan 24 '15 at 10:07
  • @LearnCocos2D thanks for the comment, I'm sure this will be really useful for me sometime in the near future! Although for my case, that answer works perfectly and doesn't mess up even after a "pause" menu. – user2995344 Jan 27 '15 at 19:03
0

If I understand your question correctly and you are trying to prevent from calling the code inside of touchesBegan more frequently than every 2 seconds, you can add a NSDate variable and set it with current date when the code is executed. Then add something like

if NSDate().timeIntervalSinceDate(timeStamp) > 2 {
    // execute your code
    for touch in touches {

         var location = touch... 
         increment()
        }
    }
    timeStamp = NSDate() // wait period starts again

}

The example is in Swift, not Objective C, I hope it is ok.

MirekE
  • 11,515
  • 5
  • 35
  • 28
0

Alternative method for sprite-kit.

int i;

-(void)increment
{
     [self runAction:[SKAction sequence:@[[SKAction waitForDuration:2.0], [SKAction runBlock:^{
        i++;
    }]]]];
}
Valar Morghulis
  • 916
  • 1
  • 9
  • 26
-2

So I think you could use temporary data storage like CoreData. But it's not necessary at your situation. PList or NSUserDefault better way to store cached value or kind of data. Store last 2 second after that in your method create an "if condition" and you can specify NSTimer method with delay.

serhat sezer
  • 1,330
  • 1
  • 10
  • 26