iphone - 如何在 iPhone 秒表应用程序中实现圈数

标签 iphone objective-c nsdate nstimer stopwatch

我正在构建一个以秒表为辅助功能的应用程序。我正在尝试做一些与 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];
}

最佳答案

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

也就是说,我将如何实现秒表:您需要两个实例变量, NSTimer 计时器NSDate 开始日期。对于单圈功能,您需要另一个,NSMutableArray 圈数。你的两个按钮很好,使用简单的逻辑,你可以决定点击时必须做什么(未经测试的代码!):

开始/停止按钮

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 是否为零。对于圈数,您只需循环遍历 laps 数组并计算 startDate 与数组中的日期之间的差异,甚至计算数组中日期之间的差异。

希望这会有所帮助!

关于iphone - 如何在 iPhone 秒表应用程序中实现圈数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6873627/

相关文章:

ios - 如何创建更小的迷你相机 View ,如 Tumblr iPhone 应用程序图像选择器

ios - 使用 CLLocationManager 监控所有可用的信标区域

objective-c - 设置核心数据对象的标量属性时的 EXC_BAD_ACCESS (IOS 5)

objective-c - dateWithTimeIntervalSince1970 没有返回正确的日期

objective-c - iPhone如何有效地获取具有NSDate属性的第一个和最后一个Core Data实体?

ios - 从 Parse SDK 日期显示本地时间

iPhone 核心数据因 ARC 崩溃

iphone - iOS6设备旋转受到限制

ios - iPhone在基础结构代码上崩溃

c++ - 在 Objective-C 中,如何将方法转发给特定的父类(super class)