使用NSTimer的秒表不正确地包括显示中的暂停时间 [英] Stopwatch using NSTimer incorrectly includes paused time in display
问题描述
这是我的iPhone秒表的代码。它按预期工作,停止和单击按钮时恢复。
This is my code for an iPhone stopwatch. It works as expected and stops and resumes when the buttons are clicked.
然而,当我点击停止时,定时器将不会在后台停止运行,当我点击开始恢复它,它会更新时间并跳到当前位置,而不是从停止时间恢复。
When I hit "Stop", however, the timer won't stop running in the background, and when I hit "Start" to resume it, it will update the time and skip to where it is currently instead of resuming from the stopped time.
如何停止 NSTimer
?是什么原因导致这种情况发生?
How can I stop the NSTimer
? What is causing this to occur?
@implementation FirstViewController;
@synthesize stopWatchLabel;
NSDate *startDate;
NSTimer *stopWatchTimer;
int touchCount;
-(void)showActivity {
NSDate *currentDate = [NSDate date];
NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate:startDate];
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"mm:ss.SS"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
NSString *timeString=[dateFormatter stringFromDate:timerDate];
stopWatchLabel.text = timeString;
[dateFormatter release];
}
- (IBAction)onStartPressed:(id)sender {
stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:1/10 target:self selector:@selector(showActivity) userInfo:nil repeats:YES];
touchCount += 1;
if (touchCount > 1)
{
[stopWatchTimer fire];
}
else
{
startDate = [[NSDate date]retain];
[stopWatchTimer fire];
}
}
- (IBAction)onStopPressed:(id)sender {
[stopWatchTimer invalidate];
stopWatchTimer = nil;
[self showActivity];
}
- (IBAction)reset:(id)sender; {
touchCount = 0;
stopWatchLabel.text = @"00:00.00";
}
推荐答案
始终使用计时器的原始开始时间,因此暂停后的显示包括计时器暂停的时间间隔。
Your calculation of the current display always uses the original start time of the timer, so the display after pausing includes the interval that the timer was paused.
最简单的操作是存储另一个 NSTimeInterval
,例如 secondsAlreadyRun
,并将其添加到您恢复时计算的时间间隔。您需要每次定时器开始计数时更新定时器的 startDate
。在 reset:
中,您还会清除 secondsAlreadyRun
间隔。
The easiest thing to do would be to store another NSTimeInterval
, say secondsAlreadyRun
, when the timer is paused, and add that to the time interval you calculate when you resume. You'll want to update the timer's startDate
every time the timer starts counting. In reset:
, you would also clear out that secondsAlreadyRun
interval.
-(void)showActivity:(NSTimer *)tim {
NSDate *currentDate = [NSDate date];
NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate:startDate];
// Add the saved interval
timeInterval += secondsAlreadyRun;
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"mm:ss.SS"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
NSString *timeString=[dateFormatter stringFromDate:timerDate];
stopWatchLabel.text = timeString;
[dateFormatter release];
}
- (IBAction)onStartPressed:(id)sender {
stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:1/10
target:self
selector:@selector(showActivity:)
userInfo:nil
repeats:YES];
// Save the new start date every time
startDate = [[NSDate alloc] init]; // equivalent to [[NSDate date] retain];
[stopWatchTimer fire];
}
- (IBAction)onStopPressed:(id)sender {
// _Increment_ secondsAlreadyRun to allow for multiple pauses and restarts
secondsAlreadyRun += [[NSDate date] timeIntervalSinceDate:startDate];
[stopWatchTimer invalidate];
stopWatchTimer = nil;
[startDate release];
[self showActivity];
}
- (IBAction)reset:(id)sender; {
secondsAlreadyRun = 0;
stopWatchLabel.text = @"00:00.00";
}
不要忘记释放 startDate
某处适当!还要记住,记录的
NSTimer
接口是为你接受一个参数的方法,它将是计时器本身。
Don't forget to release that startDate
somewhere appropriate! Also keep in mind that the documented NSTimer
interface is for the method you give it to accept one argument, which will be the timer itself. It seems to work without that, but why tempt fate?
最后,由于你使用 NSDateFormatter
,所以很多,你可能想考虑把它作为一个ivar或把它放在 showActivity:
中的 static
Finally, since you're using that NSDateFormatter
so much, you might want to consider making it an ivar or put it in static
storage in showActivity:
, like so:
static NSDateFormatter * dateFormatter = nil;
if( !dateFormatter ){
dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"mm:ss.SS"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
}
这篇关于使用NSTimer的秒表不正确地包括显示中的暂停时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!