Question

I've got a simple countdown timer method that runs when the user clicks on a button.

When the user clicks the button, the countdown timer starts counting down every second. But I noticed that if you click really fast on the button the method will run multiple times causing the countdown timer to accelerate and freak out. If you just click once with a "relaxed" click it worked as it should.

Now I tried to disable the button after the click but that only disables the button on a single click, the problem still occurs if I click on the button multiple times and fast.

Here are my methods:

    #pragma mark -
    #pragma mark startTimerButtonClicked

    - (IBAction)startTimerButtonClicked:(UIButton *)sender
    {
        if (!self.timerIsRunning) // Run timer only if it's not allready running
        {
            [self setupTimer]; // Start the timer
        }
        else
        {
            NSLog(@"Timer should pause with secondsCounter: %d and not continue to run", secondsCounter);
        }
    }

    #pragma mark -
    #pragma mark setupTimer

    - (void)setupTimer
    {
        /* -- Timer -- */
        self.timerWorkOutCountDown = [NSTimer scheduledTimerWithTimeInterval:1.0
                                                               target:self
                                                             selector:@selector(startTimer)
                                                             userInfo:nil
                                                              repeats:YES];
    }

    #pragma mark -
    #pragma mark Start timer

    - (void)startTimer
    {
        self.timerIsRunning = YES;

        secondsCounter = workOutSecondsCounter - 1;
        int minutes = secondsCounter / 60;
        int seconds = secondsCounter - (minutes * 60);

        NSString *timerOutput = [NSString stringWithFormat:@"00:%02d",seconds];

        [labelTimerCountDown setText:timerOutput];

        if (secondsCounter == 0)
        {
            [self resetTimerWithCount:0 andString:@"00:00"];
        }
    }

    #pragma mark -
    #pragma mark Reset timer

    - (void)resetTimerWithCount:(int)count andString:(NSString *)string
    {
        self.timerIsRunning = NO;

        secondsCounter = count;

        [timerWorkOutCountDown invalidate];
        timerWorkOutCountDown = nil;

        [labelTimerCountDown setText:string];
    }

    #pragma mark -
    #pragma mark resetTimerButtonClicked

    - (IBAction)resetTimerButtonClicked:(UIButton *)sender
    {
        [self resetTimerWithCount:20 andString:@"00:20"];
        NSLog(@"Reset timer secondsCounter: %d", secondsCounter);
    }

I'm guessing there is some control you can do to make the button only start the timer once, I've tried with a "buttonClickTracker" but that didn't solve the problem. I would really like to prevent that this rapid click scenario occurs, so I would be glad for any help I can get. :)

Was it helpful?

Solution

In your action method, after you check that the timer is not running, but before you set up the time, change the check value to YES:

- (IBAction)startTimerButtonClicked:(UIButton *)sender
{
    if (!self.timerIsRunning) // Run timer only if it's not allready running
    {
        // Time is running now
        self.timerIsRunning = YES;
        [self setupTimer]; // Start the timer
    }
    else
    {
        NSLog(@"Timer should pause with secondsCounter: %d and not continue to run", secondsCounter);
    }
}

If you don't do this here—or in -setupTimer there is a 1 second window where more taps will cause more timers since the timer doesn't fire until the first second is up.

OTHER TIPS

Try using this :

- (IBAction)startTimerButtonClicked:(UIButton *)sender
{
    UIButton *button = (UIButton*) sender;
    buttonname.userInteractionEnabled = NO;
    if (!self.timerIsRunning) // Run timer only if it's not allready running
    {
        [self setupTimer]; // Start the timer
    }
    else
    {
        NSLog(@"Timer should pause with secondsCounter: %d and not continue to run", secondsCounter);
    }
    buttonname.userInteractionEnabled = YES;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top