导航到另一个视图后重置 NSTimer [英] Reset NSTimer after navigating to another view
问题描述
目前我正在开发一个需要秒表的游戏,比如 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屋!