3

我正在构建一个具有秒表作为其附件功能的应用程序。我正在尝试做一些与 iOS 秒表非常相似的事情。我停止了,重置功能工作但我无法开始(一旦它停止并且用户单击开始)并且圈功能正常工作。我试图四处寻找这个问题,但除了一次启动和重置秒表教程之外我找不到任何东西。这就是我现在所拥有的。任何人都可以用这个功能帮助我吗?

// Stop Watch Code Begins

- (void)updateTimer
{
NSDate *currentDate = [NSDate date];
NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate:startDate];
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"HH:mm:ss.SSS"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
NSString *timeString=[dateFormatter stringFromDate:timerDate];
stopWatchLable.text = timeString;
[dateFormatter release];

}

 -(IBAction)startTapped:(id)sender
{
if ([self.start.titleLabel.text isEqualToString:@"Start"])
{
    NSLog(@"Start Tapped");
    [self.start setTitle:@"Stop" forState:UIControlStateNormal];
    [self.reset setTitle:@"Lap" forState:UIControlStateNormal];

    self.startDate =[NSDate date];
    stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/10.0
                                                      target:self
                                                    selector:@selector(updateTimer)
                                                    userInfo:nil
                                                     repeats:YES];

 }
else if ([self.start.titleLabel.text isEqualToString:@"Stop"])
{
    NSLog(@"Stop Tapped");
    [self.start setTitle:@"Start" forState:UIControlStateNormal];
    [self.reset setTitle:@"Reset" forState:UIControlStateNormal];

    [stopWatchTimer invalidate];
    stopWatchTimer = nil;
    [self updateTimer]; 
}
}
-(IBAction)resetTapped:(id)sender
{   
if ([self.reset.titleLabel.text isEqualToString:@"Reset"])
{
    NSLog(@"Reset Tapped");
    [stopWatchTimer invalidate];
    stopWatchTimer = nil;
    [stopWatchLable setText:@"00:00:00.000"];
}
else if ([self.reset.titleLabel.text isEqualToString:@"Lap"])
{
    NSLog(@"Lap Tapped");        
}
}
-(IBAction)hideTapped:(id)sender
{
CGRect screenRect = [[UIScreen mainScreen] applicationFrame];
CGRect endFrame = self.stopWatchView.frame;
endFrame.origin.y = screenRect.origin.y + screenRect.size.height;

// start the slide down animation
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];

// we need to perform some post operations after the animation is complete
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(slideDownDidStop)];

self.stopWatchView.frame = endFrame;
[UIView commitAnimations];

// grow the table back again in vertical size to make room for the date picker
CGRect newFrame = self.tableView.frame;
newFrame.size.height += self.stopWatchView.frame.size.height;
self.tableView.frame = newFrame;
//self.tableView.frame = screenRect;

[stopWatchTimer invalidate];
stopWatchTimer = 0;
[stopWatchLable setText:@"00:00:00.000"];
[self updateTimer];
}
4

1 回答 1

2

不要采取错误的方式,但是您的代码中有一个错误的设计选择:您不应该依赖按钮文本来告诉您要做什么——如果将来某个时候您本地化您的应用程序将不得不重做计时器。

也就是说,这就是我实现秒表的方式:您需要两个实例变量NSTimer timerNSDate startDate。对于 lap 功能,您需要另一个NSMutableArray laps。你的两个按钮很好,使用简单的逻辑你可以决定你在点击时要做什么(未经测试的代码!):

开始/停止按钮

if (!timer) {
    self.startDate = [NSDate date];
    self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 / 10.0
                                                  target:self
                                                selector:@selector(updateTimer)
                                                userInfo:nil
                                                 repeats:YES];
    [self updateTimer];
    // set button text to STOP and LAP
}

// there already is a timer, stopwatch running, so we want to stop
else {
    if ([timer isValid]) {
        [timer invalidate];
    }
    self.timer = nil;
    [self updateTimer];
    // set button text to START and RESET
}

重置/圈数按钮

// if we have a timer, we want to take a lap
if (timer) {
    if (!laps) {
        self.laps = [NSMutableArray array];
    }
    [laps addObject:[NSDate date]];
    [self updateTimer];
}

// there is no timer, so we want to reset
else {
    self.startDate = nil;
    [self updateTimer];

    // delete all laps
    self.laps = nil;
}

现在你只需要修改updateTimer来做你想做的事。在 updateTimer 中,您还应该在计算任何内容之前检查startDate是否为 nil。对于圈数,您可以遍历laps数组并计算startDate和数组中的日期之间的差异,甚至是数组中的日期之间的差异。

我希望这有帮助!

于 2011-07-29T15:48:35.893 回答