导航到另一个视图后重置NSTimer

时间:2013-05-22 10:28:51

标签: iphone nstimer reset

目前我正在开发一款需要秒表说1分钟的游戏,当用户点击进入游戏画面的游戏按钮时,我希望运行秒表计数1分钟01:00,00:59 ,00:58等因为这个原因,我搜索并发现NSTimer是实现秒表的理想选择。因为我拿了一个标签,创建了一个NSTimer的实例,分配了时间间隔并开始递减计时器标签中的值,即:

-(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];
}

这里的问题是计时器开始运行01:00,00:59,00:58然后继续,比如第53秒,我导航到另一个视图然后回来,它从00:53,00运行: 52等等,但是我希望它从01:00开始运行,为此我在viewDidDisappear中实现了无效的NSTimer,即

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

仍然存在同样的问题!

对此问题进行了大量研究,发现没有任何有用且有效的答案。

有人可以指导我,感谢任何帮助。

提前感谢每一位:)

1 个答案:

答案 0 :(得分: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的调用时,同样,在执行任何其他操作之前,请确保先在方法中调用超级