NSTimer Pause not working

2019-07-20 19:58发布

问题:

I have setup three buttons with start,stop,pause. and given controls to NSTimer to calculates.start stop button works fine gives me the start and stop time but pausebutton does not gives me accurate time .it actually pause time ..but start again it adds the paused timed and disp[ay. supoose i pause at 5 second of start and wait for 5 sec then press start...it should display 5 ...but displaying 10..

-(void)start:(NSTimer *)timer
{
  if(_timer==nil)
  {
    startDate =[NSDate date];

    _timer=[NSTimer scheduledTimerWithTimeInterval:0.25 target:self selector:@selector(timer:) userInfo:nil repeats:YES];
  }

  if(_timer!=nil)
  { 
    float pauseTime = -1*[pauseStart timeIntervalSinceNow];

    [_timer setFireDate:[previousFireDate initWithTimeInterval:pauseTime sinceDate:previousFireDate]];
  }

}

-(void)timer:(NSTimer *)timer
{
  NSInteger secondsSinceStart = (NSInteger)[[NSDate date] timeIntervalSinceDate:startDate];

  NSInteger seconds = secondsSinceStart % 60;
  NSInteger minutes = (secondsSinceStart / 60) % 60;
  NSInteger hours = secondsSinceStart / (60 * 60);
  NSString *result = nil;
  if (hours > 0) 
  {
    result = [NSString stringWithFormat:@"%02d:%02d:%02d", hours, minutes, seconds];
  }
  else 
  {
    result = [NSString stringWithFormat:@"%02d:%02d", minutes, seconds];        
  }

  label.text=result;

  NSLog(@"time interval -> %@",result);
}

-(void)stop
{
  if(_timer!=nil)
  {
    endDate = [NSDate date];
 NSLog(@"endate%@",endDate);

     NSTimeInterval interval = [endDate timeIntervalSinceDate:startDate];
NSLog(@"total time %f",interval);
    [_timer invalidate];
    _timer = nil; 
  startDate=nil;
  }
}

-(void)pause:(NSTimer *)timer
{
  pauseStart = [NSDate dateWithTimeIntervalSinceNow:0];

  previousFireDate = [_timer fireDate];

  [_timer setFireDate:[NSDate distantFuture]];
}

回答1:

I have created this applicaion on mac os. I think you can understand the logic and even copy this with minor changes...as for UILabel.

In .h

@interface AppDelegate : NSObject <NSApplicationDelegate>

@property (assign) IBOutlet NSWindow *window;

- (IBAction)start:(id)sender;
- (IBAction)pause:(id)sender;
- (IBAction)stop:(id)sender;
@property (strong) IBOutlet NSTextField *label;

@property (strong)NSDate *startDate;
@property (strong)NSTimer *timer;

@property (assign)BOOL isRunning;
@property (assign)BOOL isPaused;

@property(assign)NSInteger secondsSinceStart;

@property(assign)NSInteger secondsPaused;
@end

In .m

#import "AppDelegate.h"

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    self.label.stringValue=@"00:00:00";
    self.isRunning=NO;
    self.isPaused=NO;
    self.secondsPaused=0;
}

-(void)timerDisplay{

    if (self.isPaused) {
        self.secondsPaused++;
        return;
    }

    self.secondsSinceStart+=1;

    NSInteger seconds = self.secondsSinceStart % 60;
    NSInteger minutes = (self.secondsSinceStart / 60) % 60;
    NSInteger hours = self.secondsSinceStart / (60 * 60);
    NSString *result = nil;


    if (self.isRunning && !self.isPaused) {
        result = [NSString stringWithFormat:@"%02ld:%02ld:%02ld", hours, minutes, seconds];
        self.label.stringValue=result;
    }
}


- (IBAction)start:(id)sender {
    self.isRunning=!self.isRunning;
    self.isPaused=NO;
    self.secondsSinceStart=0;
    self.label.stringValue=@"00:00:00";


    self.startDate =[NSDate date];
    if (!self.timer) {
        self.timer=[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerDisplay) userInfo:nil repeats:YES];
    }
}

- (IBAction)pause:(id)sender {
    self.isPaused=!self.isPaused;
    NSLog(@"pause : %d",self.isPaused);
}

- (IBAction)stop:(id)sender {
    self.isRunning=NO;
    NSLog(@"start : %@",self.startDate);
    NSLog(@"end : %@",[NSDate date]);
    NSLog(@"paused : %ld",self.secondsPaused);

    NSInteger totalTime=self.secondsSinceStart+self.secondsPaused;

    NSInteger seconds = totalTime % 60;
    NSInteger minutes = (totalTime / 60) % 60;
    NSInteger hours = totalTime / (60 * 60);
    NSString *result = result = [NSString stringWithFormat:@"%02ld:%02ld:%02ld", hours, minutes, seconds];
    NSLog(@"Total : %@",result);

}
@end


回答2:

It will never ever work for you because NSTimer cant be pause, it will Start and It will only Stop when you will invalidate it. when it will in valid state it means it is running and when the state is not valid it means Timer is stopped. Thanks