【问题标题】:Stopwatch start button resets timer秒表开始按钮重置计时器
【发布时间】:2014-04-15 17:37:26
【问题描述】:

我正在制作一个基本的秒表,但是,每次我启动计时器时,单击停止,然后再次开始想要继续我的计时器,时钟从 0 重新开始。我不太确定该怎么做,因为我刚刚选择了上 obj-c/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

【问题讨论】:

  • 看来问题出在这一行:totalTimeInterval = timeInterval;您每次都重置 totalTimeInterval,而不是向当前总和添加新的时间间隔。
  • @VladimirPopko 代码不是问题。 totalTimeInterval 意味着开始时间和当前时间之间的差异,这就是它的作用。问题是每次运行计时器时都会重置开始时间。

标签: ios objective-c timer stopwatch


【解决方案1】:

每次点击“开始”,这段代码都会运行:

self.startDate = [NSDate date];

这会重置您正在使用的开始时间。把它移到某个地方,这样它只会发生一次,而不是每次启动计时器时都会发生,我认为结果会更接近你想要的。也许您可以只存储一个额外的BOOL,它会在第一次启动计时器时被切换。

编辑:

我忽略了 Stonz2 提出的非常好的观点。以这种方式执行此操作将导致时间在您重新启动后跳过。为了解决这个问题,您需要在停止计时器时存储一个单独的NSDate,以表示“暂停”时间。然后,当您再次启动计时器时,您需要将“暂停”时间添加到“开始”时间,以便继续流畅。

编辑2:

我把它扔到一个项目中,这里有一些工作代码。

我添加了一个额外的属性:

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

    }
}

【讨论】:

  • 如果汤姆计算他的总时间相同,这不会考虑“暂停”时间,因为他只是计算current time - start time
  • @Stonz2 这是一个很好的观点,我会在我的回答中考虑到这一点。
  • @Dima 也许我做错了什么,因为当我点击开始时,应用此代码后没有任何反应。
  • @Dima 我猜更多,你在我的 onStartPressed 中将上面提到的这段代码添加到哪里
  • @Dima 非常感谢。你非常有帮助。
【解决方案2】:

这是因为您在onStartPressed 方法中重置了self.startDate。仅在 viewDidLoad:onResetPressed: 中执行此操作

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多