0

Currently I am developing a game which needs a stop watch say 1 minute,when user taps the play button it enters the game screen,I want the to run the stop watch count down of 1 minute 01:00,00:59,00:58 etc. For that reason I searched and found NSTimer would be the ideal choice to implement a stop watch.Hence I took a label,created an instance of NSTimer,assigned time interval and started decrementing the value in timer label,i.e.:

-(void)viewDidAppear:(BOOL)animated
{
    self.stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(viewWillAppear:) userInfo:nil repeats:YES];
    [super viewDidAppear:YES];
}

-(void)viewWillAppear:(BOOL)animated
{
    static int currentTime = 60;
    int newTime = currentTime--;
    int minutesRemaining = newTime / 60; // integer division, truncates fractional part
    int secondsRemaining = newTime % 60; // modulo division

    self.timerLabel.text = [NSString stringWithFormat:@"%02d:%02d", minutesRemaining, secondsRemaining];

    if ([self.timerLabel.text isEqualToString:@"00:00"])
    {
        [stopWatchTimer invalidate];
    }
    [super viewWillAppear:YES];
}

The problem here is the timer starts running 01:00,00:59,00:58 and goes on,say at 53rd second,I navigated to another view and came back,it is running from 00:53,00:52 and so on,but I want it to run from 01:00 and for that I implemented invalidating NSTimer in viewDidDisappear i.e.

-(void)viewDidDisappear:(BOOL)animated
{
    if ([stopWatchTimer isValid])
    {
        [stopWatchTimer invalidate];
        self.stopWatchTimer = nil;
    }
    [super viewDidDisappear:YES];
}

Still the same issue exists!

Done lots of Research on the issue and found no answer useful and working.

Can some one please guide me,any help is appreciated.

Thanks every one in advance :)

4

1 回答 1

1

您正在使用viewWillAppear计时器的选择器。viewWillAppear是 viewController 上的一个方法,当视图出现在屏幕上时会被调用,你不应该自己调用它。相反,创建您自己的方法来减少计时器:

-(void)viewDidAppear:(BOOL)animated
{
  [super viewDidAppear:animated];
  self.stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateTime:) userInfo:nil repeats:YES];
  currentTime = 60; // This could be an instance variable
  self.timerLabel.text = @"01:00";
}


-(void)updateTime {
  int newTime = currentTime--;
  int minutesRemaining = newTime / 60; // integer division, truncates fractional part
  int secondsRemaining = newTime % 60; // modulo division

  self.timerLabel.text = [NSString stringWithFormat:@"%02d:%02d", minutesRemaining, secondsRemaining];

  if ([self.timerLabel.text isEqualToString:@"00:00"])
  {
      [self.stopWatchTimer invalidate];
  }
}

-(void)viewDidDisappear:(BOOL)animated
{
 [super viewDidDisappear:animated];
  if ([self.stopWatchTimer isValid])
  {
    [self.stopWatchTimer invalidate];
    self.stopWatchTimer = nil;
  }
}

使用这种技术,计时器负责每秒调用一次,但几秒钟后您可能会遇到计时问题。要获得更准确的计时,您应该存储开始倒计时的时间,然后在每次updateTime通话时,将当前时间与存储的开始时间进行比较。

添加到您的界面:

@property (nonatomic) NSTimeInterval startTime;

然后在实现中:

-(void)viewDidAppear:(BOOL)animated
{
    self.startTime = [NSDate timeIntervalSinceReferenceDate];
    self.duration = 60; // How long the countdown should be
    self.stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:0.1
                                                           target:self
                                                         selector:@selector(updateTime)
                                                         userInfo:nil
                                                          repeats:YES];
    self.timerLabel.text = @"01:00"; // Make sure this represents the countdown time
}

-(void)updateTime {

  int newTime = self.duration - (round([NSDate timeIntervalSinceReferenceDate] - self.startTime));
  int minutesRemaining = newTime / 60; // integer division, truncates fractional part
  int secondsRemaining = newTime % 60; // modulo division

  self.timerLabel.text = [NSString stringWithFormat:@"%02d:%02d", minutesRemaining, secondsRemaining];

  if (newTime < 1)
  {
    [self.stopWatchTimer invalidate];

    /* Do more stuff here */

  }
}

-(void)viewDidDisappear:(BOOL)animated
{
 [super viewDidDisappear:animated];
  if ([self.stopWatchTimer isValid])
  {
    [self.stopWatchTimer invalidate];
    self.stopWatchTimer = nil;
  }
}

对代码的一些额外(不相关)注释:

实现时viewDidDisappear:animated参数传递给对 super 的调用:[super viewDidDisappear:animated]; 在实现viewDidAppear:animated参数传递给对super的调用时,请确保在方法中首先调用super,然后再执行其他任何操作

于 2013-05-22T11:17:03.930 回答