6

I am trying to create a simple Countdown Timer so that when a player enters my game the timer begins from 60 down to 0. It seems simple but I am getting confused at how I write this.

So far I have created a method within my GameController.m that looks like this:

-(int)countDownTimer:(NSTimer *)timer {
    [NSTimer scheduledTimerWithTimeInterval:-1
                                 invocation:NULL
                                    repeats:YES];
    reduceCountdown = -1;
    int countdown = [[timer userInfo] reduceCountdown];
    if (countdown <= 0) {
        [timer invalidate];
    }
    return time;
}

At the start of the game I initialise the integer Time at 60. The label is then being set within ViewController. But at the moment when I compile the code it just shows the label at 60 and doesn't decrement at all.

Any help would be greatly appreciated - I am new to Objective-C.


EDIT

With some assistance from I have now separated the code into 2 separate methods. The code now looks like this:

-(void)countDown:(NSTimer *)timer {
    if (--time == 0) {
        [timer invalidate];
        NSLog(@"It's working!!!");
    }
}

-(void)countDownTimer:(NSTimer *)timer {
    NSLog(@"Hello");
    [NSTimer scheduledTimerWithTimeInterval:1
                                      target:self
                             selector:@selector(countDown:)
                                      userInfo:nil
                                      repeats:YES];
}

HOWEVER, the code is still not running properly and when I call the method [game countDownTimer] from my View Controller it breaks saying: "unrecognized selector sent to instance". Can anybody explain what is wrong here?

commanda
  • 4,841
  • 1
  • 25
  • 34

3 Answers3

12

Several things are wrong with your code:

  • You are passing a wrong parameter for the time interval - negative numbers are interpreted as the 0.1 ms
  • You are calling the wrong overload - you are expected to pass an invocation object, yet you are passing a NULL
  • You put the code that you want executed on timer together with timer initialization - the code that needs to be executed on timer should go into a separate method.

You should call the overload that takes a selector, and pass 1 for the interval, rather than -1.

Declare NSTimer *timer and int remainingCounts, then add

timer = [NSTimer scheduledTimerWithTimeInterval:1
                                         target:self
                                       selector:@selector(countDown)
                                       userInfo:nil
                                        repeats:YES];
remainingCounts = 60;

to the place where you want to start the countdown. Then add the countDown method itself:

-(void)countDown {
    if (--remainingCounts == 0) {
        [timer invalidate];
    }
}
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • wouldn't it fire once more than he wants to that way? I think it should be `--remainingCounts == 0` ,no? – Daij-Djan Mar 09 '13 at 14:18
  • @Daij-Djan You are right, it should be either `remainingCounts = 59` or `--remainingCounts`. Thanks! – Sergey Kalinichenko Mar 09 '13 at 14:30
  • Thanks for your feedback dasblinkenlight. However, still struggling to get it running! At the moment my selector is not communicating with the countDown method i.e. nothing is happening when I compile the code. Could this be because the timer has not started or that they are not linked? – Matthew Nieuwenhuys Mar 09 '13 at 14:42
  • @MatthewNieuwenhuys This could be necause of any of the reasons that you mention. Make sure that timer is an instance variable, that the call to scheduled timer with interval is happening (add NSLog) and that countDown is on the same class as the call that sets up the timer. Add NSLog as necessary to see what gets called. – Sergey Kalinichenko Mar 09 '13 at 14:55
  • Thanks dasblinkedlight, this may be a silly question but I need to initiate the countDownTimer from my view controller.m - so far I have put [game countDownTimer]; - what do I need to add to start the countDownTimer from my view controller? – Matthew Nieuwenhuys Mar 09 '13 at 15:31
  • @MatthewNieuwenhuys You need to add the call to the viewDidAppear method of your view controller. Again, add NSLog to see if it got called or not. – Sergey Kalinichenko Mar 09 '13 at 15:51
  • Still struggling with getting the code working properly, I have spent a few hours playing around but keep hitting a brick wall. Would you be able to look at my edited post? Appreciate your help. – Matthew Nieuwenhuys Mar 10 '13 at 00:05
  • @MatthewNieuwenhuys The unrecognized selector exception is because the signature of the method that you are calling does not match the signature of the method that you defined. You need to remove the `:(NSTimer *)timer` part from the method signature, because you are not using the `timer` inside the method anyway. – Sergey Kalinichenko Mar 10 '13 at 00:29
2

Try this

- (void)startCountdown
{
    _counter = 60;

    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1
                                                      target:self
                                                    selector:@selector(countdownTimer:)
                                                    userInfo:nil
                                                     repeats:YES];
}

- (void)countdownTimer:(NSTimer *)timer
{
    _counter--;
    if (_counter <= 0) { 
        [timer invalidate];
        //  Here the counter is 0 and you can take call another method to take action
        [self handleCountdownFinished];
   }
}
bbarnhart
  • 6,620
  • 1
  • 40
  • 60
1

From the question you posed.you can achieve that by invoking a function for every 1 sec and handle the decrement logic in that.

Snippet:-

NSTimer *t = [NSTimer scheduledTimerWithTimeInterval: 1.0
                      target: self
                      selector:@selector(onTick:)
                      userInfo: nil repeats:YES];
(void)onTick
{
   //do what ever you want
   NSLog(@"i am called for every 1 sec");
//invalidate after 60 sec [timer invalidate];
}