NSTimer problem

后端 未结 2 480
野的像风
野的像风 2020-12-03 20:32

So I am trying to set up a basic timer but I am failing miserably. Basically all I want is to start a 60 second timer when the user clicks a button, and to update a label wi

相关标签:
2条回答
  • 2020-12-03 20:36

    Ok, well for starters, check this out if you haven't already: Official Apple Docs about Using Timers

    Based on your description, you probably want code that looks something like this. I've made some assumptions regarding behavior, but you can suit to taste.

    This example assumes that you want to hold on to a reference to the timer so that you could pause it or something. If this is not the case, you could modify the handleTimerTick method so that it takes an NSTimer* as an argument and use this for invalidating the timer once it has expired.

    @interface MyController : UIViewController
    {
      UILabel * theLabel;
    
      @private
      NSTimer * countdownTimer;
      NSUInteger remainingTicks;
    }
    
    @property (nonatomic, retain) IBOutlet UILabel * theLabel;
    
    -(IBAction)doCountdown: (id)sender;
    
    -(void)handleTimerTick;
    
    -(void)updateLabel;
    
    @end
    
    @implementation MyController
    @synthesize theLabel;
    
    // { your own lifecycle code here.... }
    
    -(IBAction)doCountdown: (id)sender
    {
      if (countdownTimer)
        return;
    
    
      remainingTicks = 60;
      [self updateLabel];
    
      countdownTimer = [NSTimer scheduledTimerWithTimeInterval: 1.0 target: self selector: @selector(handleTimerTick) userInfo: nil repeats: YES];
    }
    
    -(void)handleTimerTick
    {
      remainingTicks--;
      [self updateLabel];
    
      if (remainingTicks <= 0) {
        [countdownTimer invalidate];
        countdownTimer = nil;
      }
    }
    
    -(void)updateLabel
    {
      theLabel.text = [[NSNumber numberWithUnsignedInt: remainingTicks] stringValue];
    }
    
    
    @end
    
    0 讨论(0)
  • 2020-12-03 20:55

    It may be a little late to post a second answer to this question but I've been looking for a good place to post my own solution to this problem. In case it is of use to anyone here it is. It fires 8 times but of course this can be customised as you please. The timer deallocates itself when time is up.

    I like this approach because it keeps the counter integrated with the timer.

    To create an instance call something like:

    SpecialKTimer *timer = [[SpecialKTimer alloc] initWithTimeInterval:0.1 
                                                             andTarget:myObject
                                                           andSelector:@selector(methodInMyObjectForTimer)];
    

    Anyway, here are the header and method files.

    //Header
    
    #import <Foundation/Foundation.h>
    
    @interface SpecialKTimer : NSObject {
    
        @private
    
        NSTimer *timer;
    
        id target;
        SEL selector;
    
        unsigned int counter;
    
    }
    
    - (id)initWithTimeInterval:(NSTimeInterval)seconds
                     andTarget:(id)t
                   andSelector:(SEL)s;
    - (void)dealloc;
    
    @end
    
    //Implementation
    
    #import "SpecialKTimer.h"
    
    @interface SpecialKTimer()
    
    - (void)resetCounter;
    - (void)incrementCounter;
    - (void)targetMethod;
    
    @end
    
    @implementation SpecialKTimer
    
    - (id)initWithTimeInterval:(NSTimeInterval)seconds
                     andTarget:(id)t
                   andSelector:(SEL)s {
    
        if ( self == [super init] ) {
    
            [self resetCounter];
    
            target = t;
            selector = s;
    
            timer = [NSTimer scheduledTimerWithTimeInterval:seconds
                                                     target:self
                                                   selector:@selector(targetMethod)
                                                   userInfo:nil
                                                    repeats:YES];
    
        }
    
        return self;
    
    }
    
    - (void)resetCounter {
    
        counter = 0;
    
    }
    
    - (void)incrementCounter {
    
        counter++;
    
    }
    
    - (void)targetMethod {
    
        if ( counter < 8 ) {
    
            IMP methodPointer = [target methodForSelector:selector];
            methodPointer(target, selector);
    
            [self incrementCounter];
    
        }
    
        else {
    
            [timer invalidate];
            [self release];
    
        }
    
    }
    
    - (void)dealloc {
    
        [super dealloc];
    
    }
    
    @end
    
    0 讨论(0)
提交回复
热议问题