目前我正在开发一款需要秒表说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];
}
仍然存在同样的问题!
对此问题进行了大量研究,发现没有任何有用且有效的答案。
有人可以指导我,感谢任何帮助。
提前感谢每一位:)
答案 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的调用时,同样,在执行任何其他操作之前,请确保先在方法中调用超级