我不明白如何制作像苹果倒数计时器这样的计时器

时间:2013-07-10 20:04:56

标签: iphone ios objective-c nstimer countdown

我有一个表格视图控制器和一个由细胞连接的细节视图控制器。导航栏。在详细视图中,控制器是倒数计时器,具有用户指定的间隔。当第一次单击一个单元格以获取详细视图控制器时,它会起作用,但当回击并重新占用同一个单元格时,它会重新开始。我知道为什么,但我不知道如何解决它(它在这篇文章的最后)。这是我的代码:

任务=放在tableview单元格中的对象

taskArray =未完成的任务对象数组

completedArray =已完成任务对象的数组

TableViewController.m

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
 cellSubclassCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"];
    if (!cell)
        cell = [[cellSubclassCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"UITableViewCell"];

    if([indexPath section] == 0){
    cell.textLabel.text = [[[self.taskArray objectAtIndex:[indexPath row]] taskName] uppercaseString];

    cell.imageView.image = [UIImage imageNamed:@"unchecked.png"];
        cell.imageView.highlightedImage = [UIImage imageNamed:@"uncheckedhighlighted.png"];
        [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
        [cell setBackgroundColor:[UIColor colorWithRed:236.0/255 green:240.0/255 blue:241.0/255 alpha:1.0f]];
        cell.textLabel.textColor = baseColor;

        NSString *detailText = [[self.taskArray objectAtIndex:[indexPath row]] timeIntervalString];
        cell.detailTextLabel.text = detailText;
               [[cell detailTextLabel] setFont:[UIFont fontWithName:@"Avenir-Black" size:12]];
        [[cell textLabel] setFont:[UIFont fontWithName:@"AvenirNext-DemiBold" size:16]];
[cell.contentView setAlpha:1];
    } else if ([indexPath section] == 1) {
    cell.textLabel.text = [[[self.completedArray objectAtIndex:[indexPath row]] taskName] uppercaseString];

     cell.imageView.image = [UIImage imageNamed:@"checked.png"];
        [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
        [cell setBackgroundColor:[UIColor colorWithRed:236.0/255 green:240.0/255 blue:241.0/255 alpha:1.0f]];
        cell.textLabel.textColor = baseColor;
        NSString *detailText = [[self.completedArray objectAtIndex:[indexPath row]] timeIntervalString];
        cell.detailTextLabel.text = detailText;
        [[cell detailTextLabel] setFont:[UIFont fontWithName:@"Avenir-Black" size:12]];
        [[cell textLabel] setFont:[UIFont fontWithName:@"AvenirNext-DemiBold" size:16]];
        [cell.contentView setAlpha:0.5];
    }
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handlechecking:)];
    //cell.contentView
    [cell.imageView addGestureRecognizer:tap];
    cell.imageView.userInteractionEnabled = YES;
    return cell;
    }
-(void)handlechecking:(UITapGestureRecognizer *)t{

        CGPoint tapLocation = [t locationInView:self.tableView];
        NSIndexPath *tappedIndexPath = [self.tableView indexPathForRowAtPoint:tapLocation];
        NSIndexPath *newIndexPath = nil;

        if (tappedIndexPath.section == 0) {

            NSUInteger newRowIndex = self.completedArray.count;
            [self.completedArray addObject:[self.taskArray objectAtIndex:tappedIndexPath.row]];
            [self.taskArray removeObject:[self.taskArray objectAtIndex:tappedIndexPath.row]];
            newIndexPath = [NSIndexPath indexPathForRow:newRowIndex inSection:1];

        } else {

            NSUInteger newRowIndex = self.taskArray.count;
            [self.taskArray addObject:[self.completedArray objectAtIndex:tappedIndexPath.row]];
            [self.completedArray removeObject:[self.completedArray objectAtIndex:tappedIndexPath.row]];
            newIndexPath = [NSIndexPath indexPathForRow:newRowIndex inSection:0];
        }
        [self.tableView beginUpdates];
        [self.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
        [self.tableView deleteRowsAtIndexPaths:@[tappedIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
        [self.tableView endUpdates];

}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    NSInteger num = 0;
    if (section == 0) {
        num = self.taskArray.count;
    } else {
        num = self.completedArray.count;
    }
    return num;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    Tasks *task = [[Tasks alloc]init];
    if (indexPath.section == 0){
    task.taskName = [[self.taskArray objectAtIndex:[indexPath row]] taskName];
        task.timeInterval = [[self.taskArray objectAtIndex:[indexPath row]] timeInterval];
    task.dateCreated = [[self.taskArray objectAtIndex:[indexPath row]] dateCreated];
    } else if (indexPath.section == 1){
        task.taskName = [[self.completedArray objectAtIndex:[indexPath row]] taskName];
        task.timeInterval = [[self.completedArray objectAtIndex:[indexPath row]] timeInterval];
        task.dateCreated = [[self.completedArray objectAtIndex:[indexPath row]] dateCreated];
    }
    DetailViewController *dvc = [[DetailViewController alloc]init];
    [dvc setTestTask:task];
    [[self navigationController] pushViewController:dvc animated:YES];
}

DetailViewController.m

-(IBAction)startTimer:(id)sender{
    [sender setHidden:YES];
    [pauseButton setHidden:NO];
    [continueButton setHidden:NO];
        gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
        self.date1 = [NSDate dateWithTimeInterval:[testTask timeInterval] sinceDate:[NSDate date]];

        timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerAction:) userInfo:nil repeats:YES];
    [timer fire];

}
-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];

    [timerLabel setFont:[UIFont fontWithName:@"BebasNeue" size:60]];
    [[self navigationItem] setTitle:[testTask taskName]];
    if (startButton.hidden == NO){
        [pauseButton setHidden:YES];
        [continueButton setHidden:YES];
    } else {
        [pauseButton setHidden:NO];
        [continueButton setHidden:NO];
    }
      timeRemaining = [NSString stringWithFormat:@"%02d:%02d:%02d", [components hour], [components minute], [components second]];
    timerLabel.text = timeRemaining;
    [timerLabel setNeedsDisplay];
    [self.view setNeedsDisplay];
}
-(void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];

    [testTask setTaskName:[testTask taskName]];
    [testTask setTimeInterval:[testTask timeInterval]];

}
-(void)timerAction:(NSTimer *)t{
     NSDate *now = [NSDate date];
    components = [gregorianCalendar components:NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit  fromDate:now toDate:self.date1 options:0];

    timeRemaining = nil;
    if([now compare:self.date1] == NSOrderedAscending){
        timeRemaining = [NSString stringWithFormat:@"%02d:%02d:%02d", [components hour], [components minute], [components second]];
        NSLog(@"works %@", timeRemaining);
    } else {
        timeRemaining = [NSString stringWithFormat:@"00:00:00"];
        [self.timer invalidate];
        self.timer = nil;
        if (self.alertView == NULL){
       self.alertView = [[UIAlertView alloc]initWithTitle:[testTask taskName] message:@"Time is up!" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
        [alertView performSelectorOnMainThread:@selector(show) withObject:nil waitUntilDone:YES];       
        NSLog(@"ended");
        }
    }
   timerLabel.text = timeRemaining;
    [timerLabel setNeedsDisplay];
    [self.view setNeedsDisplay];
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex{
    self.alertView = NULL;
}

所以基本上,当应用程序在后台时,计时器应该继续(它将根据计算的时间发送警报)。这意味着当您单击并重新保留单元格时,计时器应该继续。它没有这样做的原因是因为每次我点击一个单元格(或行),DetailViewController都会被分配。我不知道如何解决这个问题,所以我可以节省时间,开始/暂停,因为我喜欢。

1 个答案:

答案 0 :(得分:0)

当您回击并以某种方式保存时,您需要跟踪计时器上的时间。您可以通过最简单的NSUserDefaults保存它,但由于您可以拥有多个计时器,因此可以更简洁地使用一个简单的CoreData应用程序。

逻辑(如果我理解你的问题):

1. User pushes to DetailView and timer starts
2. User wants to pop back
  2.1 Save the date the timer started to the task record
3. User wants to go back to same task
  3.1 Load the NSDate of when the timer started from disk
  3.2 Calculate the offset from then until now
  3.3 Add that to the clock
  3.4 Start the timer with the offset added

希望有所帮助。