导航到另一个视图后重置 NSTimer [英] Reset NSTimer after navigating to another view

查看:41
本文介绍了导航到另一个视图后重置 NSTimer的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前我正在开发一个需要秒表的游戏,比如 1 分钟,当用户点击播放按钮时,它进入游戏屏幕,我希望运行秒表倒计时 1 分钟 01:00,00:59,00:58 等原因,我搜索并发现 NSTimer 将是实现秒表的理想选择.因此我拿了一个标签,创建了一个 NSTimer 实例,分配了时间间隔并开始递减计时器标签中的值,即:

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

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

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

仍然存在同样的问题!

对该问题进行了大量研究,但没有找到有用且有效的答案.

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

有人可以指导我吗,任何帮助表示赞赏.

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

提前谢谢大家:)

推荐答案

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

You are use the selector viewWillAppear for the timer. viewWillAppear is a method on a viewController that gets called when the view appears on screen, you should not call it yourself. Instead, create your own method that decrements the timer:

-(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 调用时,将当前时间与存储的开始时间进行比较.

With this technique the timer is responsible for calling every second, but you will probably have timing issues after some seconds. To have a more accurate timing, you should store the time that you started the countdown and then on every updateTime call, compare the current time with the stored started time.

添加到您的界面:

@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;
  }
}

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

Some extra (unrelated) comments on the code:

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

when implementing viewDidDisappear: pass the animated parameter to the call to super: [super viewDidDisappear:animated]; when implementing viewDidAppear: pass the animated parameter to the call to super, also, make sure you call super first this in the method, before doing anything else

这篇关于导航到另一个视图后重置 NSTimer的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆