Кнопка запуска секундомера сбрасывает таймер
Я делаю базовый секундомер, однако каждый раз, когда я запускаю таймер, нажимаю "Стоп" и начинаю снова, желая продолжить таймер, часы перезагружаются с нуля. Я не совсем уверен, что делать, поскольку я только что подобрал объект. с /Xcode.
#import "StopwatchViewController.h"
bool stopPressed = false;
bool startPressed = false;
int startsPressed = 0;
NSTimeInterval totalTimeInterval;
@interface StopwatchViewController ()
@property (strong, nonatomic) NSTimer *stopWatchTimer; // Store the timer that fires after a certain time
@property (strong, nonatomic) NSDate *startDate; // Stores the date of the click on the start button
@end
@implementation StopwatchViewController
- (void)updateTimer
{
NSDate *currentDate = [NSDate date];
NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate: self.startDate];
totalTimeInterval = timeInterval;
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:totalTimeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat: @"HH:mm:ss.SSS"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
NSString *timeString = [dateFormatter stringFromDate:timerDate];
self.stopwatchLabel.text = timeString;
}
- (IBAction)onStartPressed:(id)sender
{
if(startsPressed < 1) {
if(startPressed) return;
startPressed = true;
stopPressed =false;
self.startDate = [NSDate date];
//create the stop watch timer that fires every 100ms
self.stopWatchTimer =
[NSTimer scheduledTimerWithTimeInterval:1.0/100.0
target:self
selector:@selector(updateTimer)
userInfo:nil
repeats:YES];
} else {
startPressed = true;
stopPressed = false;
}
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)onStopPressed:(id)sender {
if(stopPressed) return;
stopPressed = true;
startPressed = false;
[self.stopWatchTimer invalidate];
self.stopWatchTimer = nil;
[self updateTimer];
}
- (IBAction)onResetPressed:(id)sender {
if(stopPressed == false) return;
self.stopWatchTimer = 0;
NSString *timeString = @"00:00:00.000";
self.stopwatchLabel.text = timeString;
}
@end
Я сейчас нахожусь в этой точке, где мой старт
#import "StopwatchViewController.h"
bool stopPressed = false;
bool startPressed = false;
int startsPressed = 0;
NSTimeInterval totalTimeInterval;
@interface StopwatchViewController ()
@property (strong, nonatomic) NSTimer *stopWatchTimer; // Store the timer that fires after a certain time
@property (strong, nonatomic) NSDate *startDate; // Stores the date of the click on the start button
@property (nonatomic, strong) NSDate *pauseDate;
@end
@implementation StopwatchViewController
- (void)updateTimer
{
NSDate *currentDate = [NSDate date];
NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate: self.startDate];
totalTimeInterval = timeInterval;
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:totalTimeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat: @"HH:mm:ss.SSS"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
NSString *timeString = [dateFormatter stringFromDate:timerDate];
self.stopwatchLabel.text = timeString;
}
- (IBAction)onStartPressed:(id)sender
{
// if(startsPressed < 1) {
// if(startPressed) return;
// startPressed = true;
// stopPressed =false;
// self.startDate = [NSDate date];
//
// //create the stop watch timer that fires every 100ms
// self.stopWatchTimer =
// [NSTimer scheduledTimerWithTimeInterval:1.0/100.0
// target:self
// selector:@selector(updateTimer)
// userInfo:nil
// repeats:YES];
// } else {
//
// startPressed = true;
// stopPressed = false;
//
// }
if(startsPressed < 1) {
if( ! _startDate) {
self.startDate = [NSDate date];
}
else {
if(_pauseDate) {
NSTimeInterval startTime = _startDate.timeIntervalSince1970;
NSTimeInterval pauseTime = _startDate.timeIntervalSince1970;
// the actual elapsed time before we paused
NSTimeInterval elapsedTime = pauseTime - startTime;
// set a new start time to match our elapsed time.
NSTimeInterval currentTime = [NSDate date].timeIntervalSince1970;
NSTimeInterval newStartTime = currentTime - elapsedTime;
_startDate = [NSDate dateWithTimeIntervalSince1970:newStartTime];
_pauseDate = nil;
}
}
}
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)onStopPressed:(id)sender {
if(stopPressed) return;
_pauseDate = [NSDate date];
stopPressed = true;
startPressed = false;
[self.stopWatchTimer invalidate];
self.stopWatchTimer = nil;
[self updateTimer];
}
- (IBAction)onResetPressed:(id)sender {
if(stopPressed == false) return;
_startDate = nil;
_pauseDate = nil;
self.stopWatchTimer = 0;
NSString *timeString = @"00:00:00.000";
self.stopwatchLabel.text = timeString;
}
@end
2 ответа
Каждый раз, когда вы нажимаете "старт", этот код запускается:
self.startDate = [NSDate date];
Это сбрасывает начальное время, которое вы используете. Переместите это куда-нибудь так, чтобы это происходило только один раз, а не каждый раз, когда вы запускаете таймер, и я думаю, что результат будет ближе к тому, что вы хотите. Возможно, вы можете просто хранить дополнительные BOOL
который переключается при первом запуске таймера.
Редактировать:
Очень хороший момент, поднятый Stonz2, который я упустил. Если вы сделаете это таким образом, у вас будет время пропустить, как только вы запустите его снова. Для того, чтобы это исправить, вам нужно хранить отдельный NSDate
когда вы останавливаете таймер, для представления "приостановленного" времени. Затем, когда вы снова запускаете таймер, вам нужно будет добавить "приостановленное" время к "начальному", чтобы продолжение было плавным.
Edit2:
Я бросил это в проект, и вот немного рабочего кода.
Я добавил дополнительное свойство:
@property (nonatomic, strong) NSDate *pauseDate;
В onStopPressed:
Я добавил это, чтобы инициализировать время паузы:
_pauseDate = [NSDate date];
Затем в onStartPressed:
Я добавил следующий код, чтобы обеспечить единственную инициализацию startDate
и сделать математику, чтобы получить истекшее время после паузы:
// if we have a start date, don't initialize again
if(! _startDate)
{
self.startDate = [NSDate date];
}
else
{
if(_pauseDate)
{
NSTimeInterval startTime = _startDate.timeIntervalSince1970;
NSTimeInterval pauseTime = _pauseDate.timeIntervalSince1970;
// The actual elapsed time before we paused.
NSTimeInterval elapsedTime = pauseTime - startTime;
// Set a new start time to match our elapsed time.
NSTimeInterval currentTime = [NSDate date].timeIntervalSince1970;
NSTimeInterval newStartTime = currentTime - elapsedTime;
_startDate = [NSDate dateWithTimeIntervalSince1970:newStartTime];
_pauseDate = nil;
}
}
Кроме того, чтобы ваш сброс работал правильно, в onResetPressed:
вам нужно будет добавить:
_startDate = nil;
_pauseDate = nil;
Просто проверил это, и он работает как чемпион.
Edit3: полный метод согласно ветке комментариев
- (IBAction)onStartPressed:(id)sender
{
if(startsPressed < 1) {
if(startPressed) return;
startPressed = true;
stopPressed =false;
if(! _startDate)
{
self.startDate = [NSDate date];
}
else
{
if(_pauseDate)
{
NSTimeInterval startTime = _startDate.timeIntervalSince1970;
NSTimeInterval pauseTime = _pauseDate.timeIntervalSince1970;
NSTimeInterval elapsedTime = pauseTime - startTime;
NSTimeInterval currentTime = [NSDate date].timeIntervalSince1970;
NSTimeInterval newStartTime = currentTime - elapsedTime;
_startDate = [NSDate dateWithTimeIntervalSince1970:newStartTime];
_pauseDate = nil;
}
}
//create the stop watch timer that fires every 100ms
self.stopWatchTimer =
[NSTimer scheduledTimerWithTimeInterval:1.0/100.0
target:self
selector:@selector(updateTimer)
userInfo:nil
repeats:YES];
} else {
startPressed = true;
stopPressed = false;
}
}
Это потому что вы сбрасываете self.startDate
в onStartPressed
метод. Делать это только в viewDidLoad:
И в onResetPressed: