I have a simple timer using that is activated with a button is pushed. It runs from 60 to 0 no problem but what I want is to stop and reset the timer on push button. I have managed to stop it when the button is pressed using the code below but for some reason cannot get it to reset and stop at 60. This should be simple but it isn't working. Any suggestions?
Timer is set using simple Action
- (IBAction)timerStart:(id)sender {
if(!secondCounter == 0){
[countdownTimer invalidate];
}
else {
[self setTimer];
}
}
CODE FOR TIMER
- (void)timerRun {
secondCounter = secondCounter - 1;
int minutes = secondCounter;
NSString *timerOutput = [NSString stringWithFormat:#"%d", minutes ];
countDownLabel.text = timerOutput;
if(secondCounter == 0){
[countdownTimer invalidate];
countdownTimer = nil;
}
}
- (void)setTimer {
secondCounter = 60;
countdownTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(timerRun) userInfo:nil repeats:YES];
}
You need to set the seconds down to 0, otherwise the you always invalidate your timer, but never start it again:
- (IBAction)timerStart:(id)sender {
if(!secondCounter == 0) {
[countdownTimer invalidate];
secondCounter = 0;
}
else {
[self setTimer];
}
}
What do you mean to stop the timer? Timer is not going to stop. You would like to have to have countDownLabel.text to show 60? When you invalidate the timer it will stop running and calling timerRun method If you want to restart the timer just call setTimer function again. I think what you meant is to have countDownLabel.text = #"60" after [countdownTimer invalidate]; and when you click the button again the timer will start again and will change the label. Let me know if this is what you were looking for.
As Christian said you have to reset the secondCounter
secondCounter = 0;
Related
int maximumMinute;
NSTimer *timer;
- (void)startTimer: (int) minute {
maximumMinute = minute;
timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(countDown) userInfo:nil repeats:YES];
}
- (void)countDown {
maximumMinute -= 1;
self.timerLabel.text = [NSString stringWithFormat:#"%i", maximumMinute];
if (maximumMinute == 0) {
[timer invalidate];
}
}
This is my timer code and i just start the timer in viewDidLoad
i have this method called when some view is clicked for just testing.
-(void)clickSomthing: (UITapGestureRecognizer *)recognizer {
int i = 0;
while ([timer isValid])
{
NSLog(#"timer valid");
}
Firstly, when the view is loaded, the timer count is fired and i can see the time count down actually but when i click any view associated with the method "clickSomething" the timer does not count down actually it stops.
What i really want to do is that i want the timer keep going on until it reaches zero regardless of while or for loop. Actually, I am trying to stop my game based on the timer but the game does need some while loop and for loop that would take a while.
Your code lock the main thread (you never should do this) you should use GCD - Grand Central Dispatch to let the countdown in background while the user keep using the app.
-(void)clickSomthing: (UITapGestureRecognizer *)recognizer {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
int countDown = 10; // This is the countdown time
BOOL letTheCountDown = TRUE;
while (letTheCountDown) {
[NSThread sleepForTimeInterval:1.0]; // Count second by second
countDown--;
NSLog(#"countDown %i",countDown);
if (countDown == 0) {
letTheCountDown = FALSE;
dispatch_async(dispatch_get_main_queue(), ^{
// Do something in main thread here. Ex: alert
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Alert" message:#"Time is Over" delegate:self cancelButtonTitle:#"Okay" otherButtonTitles:nil];
[alert show];
});
}
}
});
}
Thank you in advance.
I am developing a game that runs on a timer. I have a label on the view *countdown. I am using a NSTimer *countdownTimer to run 120 seconds (2:00). That is when the game is over. Also, at the same time...I am running a transition timer that modals to another view controller.
I have it set up where the next view the player can select "Play Again". I have it set up where it goes back to the original view. However, how do I reset the *countdownTimer to run again from 2:00?
- (IBAction)playAgain:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
[self setTimer];
[self GameOver];
[self Score];
[self timerRun];
countdown.text = [NSString stringWithFormat:#"2:00"];
}
This is the button to play again. The countdown text does not reset. Here is my NSTimer for *countdownTimer
-(void) timerRun {
secondsCount = secondsCount - 1;
int minuts = secondsCount / 60;
int seconds = secondsCount - (minuts * 60);
NSString *timerOutput = [NSString stringWithFormat: #"%2d:%.2d", minuts, seconds];
countdown.text = timerOutput;
if (secondsCount == 0) {
[countdownTimer invalidate];
countdownTimer = nil;
}
}
-(void) setTimer {
secondsCount= 120;
countdownTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(timerRun) userInfo:nil repeats:YES];
When it resets, it just stays at zero instead of going back to 2:00
Thank you for your help.
After the end of our game the NSTimer does not stop.
-(void)StartGame{
Countdown = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(TimeDecrease) userInfo:nil repeats:YES];
}
-(void)TimeDecrease{
StartTime = StartTime - 1;
Timer.text = [NSString stringWithFormat:#"%d",StartTime];
if(StartTime == 0){
[self EndGame];
}
}
We tried [Countdown release] and disabled ARC but it throws an error.
We are trying to accomplish a timer that resets to 15 at the beginning of every new game.
Try:
[Countdown invalidate];
Countdown = nil;
So I am trying to make a countdown and when its done the game is over. Here is my code:
-(void)Movement667{
loadinglabel.text = [NSString stringWithFormat:#"Go!"];;
end =[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(Movement999)userInfo:nil repeats:YES];
}
-(void)Movement999{
if (gametime > 0){
gametime = gametime - 1;
gametimelabel.text = [NSString stringWithFormat:#"%i", gametime];
}else{
smallrock6.hidden = YES;
endlabel.hidden = NO;
highscore.hidden = NO;
highscoreannouncer.hidden = NO;
highscorebackground.hidden = NO;
highscore.text = [NSString stringWithFormat:#"%i", score];
}
}
The first time I play it everything works fine, and it counts down every second. When I play it a second time and so on it starts off normal then it counts down in greater patterns i.e. 2, 4 , 5 ect. Does anyone know why?
It's because you never stop the timer. So what happens is that when you reset the time and create a new timer there are two timers running at the same time (the selector is called twice per second), then three, four, etc. Try to keep the timer in a property and change the code as follows:
#property (strong, nonatomic) NSTimer *myTimer;//ADDDED
-(void)Movement667{
loadinglabel.text = [NSString stringWithFormat:#"Go!"];;
self.myTimer =[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(Movement999)userInfo:nil repeats:YES];//CHANGED
}
-(void)Movement999{
if (gametime > 0){
gametime = gametime - 1;
gametimelabel.text = [NSString stringWithFormat:#"%i", gametime];
}else{
[self.myTimer invalidate];//ADDED
smallrock6.hidden = YES;
endlabel.hidden = NO;
highscore.hidden = NO;
highscoreannouncer.hidden = NO;
highscorebackground.hidden = NO;
highscore.text = [NSString stringWithFormat:#"%i", score];
}
}
ADDED: If you need to interrupt your game before you run out of time you should make sure to call [self.myTimer invalidate] in that case as well.
ADDED: If you want to make sure the timer is also invalidated when your ViewController goes off screen I would suggest invalidate the timer in viewDidDisappear:
-(void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
[self.myTimer invalidate];
}
When the game is done, don't forget to invalidate your time with
[end invalidate];
Put this code in the else statement in Movement999.
It stops the receiver from ever firing again. And then you can restart the timer for a new game.
I have this app which has a timer in it and I want to be able to display a button at random points in that timer. Sort Of like a game setting where you have to get the button to get more time before it disappears. I already have some code , but the problem is that the timer that i already have is being messed up ( i can tell because it is linked to a label. It messed up because it goes down by 2 instead of 1 and this only happens when i have the code to make the button appear and disappear with the timer.
Here is the code to my timer that is being messed up:
-(IBAction)Ready:(id)sender {
[self performSelector:#selector(TimerDelay) withObject:nil afterDelay:1.0];
[self performSelector:#selector(randomTimer) withObject:nil afterDelay:0.5];
}
-(void)TimerDelay {
MainInt = 36;
timer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:#selector(countDownDuration)
userInfo:nil
repeats:YES];
}
Here is the code to the button:
-(IBAction)Ready:(id)sender { //the same ready action as above
[self performSelector:#selector(TimerDelay) withObject:nil afterDelay:1.0];
[self performSelector:#selector(randomTimer) withObject:nil afterDelay:0.5];
}
-(void)TimerDelay {
MainInt = 36;
timer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:#selector(countDownDuration)
userInfo:nil
repeats:YES];
}
- (void)randomTimer {
NSInteger randomTime = arc4random_uniform(0); //Some number between 0 and 9
timer = [NSTimer scheduledTimerWithTimeInterval:randomTime
target:self
selector:#selector(showButton)
userInfo:nil
repeats:NO];
}
- (void)showButton {
if(self.plus5.hidden == YES) {
self.plus5.hidden = NO;
}
else {
self.plus5.hidden = YES;
}
[self TimerDelay]; //Call random timer function again to run this method at a future random time
}
You are calling "randomTimer" and "TimerDelay" (this should be "timerDelay") one after the other and scheduling and REscheduling "timer".
I think you should reconsider your architecture, here...
EDIT: Use just one timer and let it manage your button.
- (void)somewhereInYourCode
{
shouldShowButton = YES;
timer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:#selector(timeFired)
userInfo:nil
repeats:YES];
}
- (void)timeFired
{
// Here your countdown and...
if (shouldShowButton) {
NSInteger randomTimeInt = arc4random_uniform(9); // as suggested by Bergasms
float randomTimeFloat = randomTimeInt;
[self performSelector:#selector(showButton) withObject:nil afterDelay:randomTimeFloat];
shouldShowButton = NO;
}
}
This way your timer won't (probably) mess up.
This:
arc4random_uniform() will return a uniformly distributed random number
less than upper_bound.
is one of your problems.
NSInteger randomTime = arc4random_uniform(0); //Some number between 0 and 9
needs to be
NSInteger randomTime = arc4random_uniform(9); //Some number between 0 and 9
I cannot say for the rest of your code. But the line you have will always return 0, which means the random timer will always execute instantly.