title: I dont understand how to make a timer like apple's countdown timer
body: <p>I have a table view controller and a detail view controller connected by the cells &amp; navigation bar. in the detail view controller is a countdown timer, with an interval specified by the user. it works when first clicking on a cell to get the detail view controller but when tapping back and retapping the same cell, it starts over. I know why, but I don't know how to fix it (its at the end of this post). Here is my code:</p>
  
  <p>Tasks = objects put in tableview cells</p>
  
  <p>taskArray = array of uncompleted task objects</p>
  
  <p>completedArray = array of completed task objects</p>
  
  <p>TableViewController.m</p>
  
  <pre><code>-(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];
  }
  </code></pre>
  
  <p>DetailViewController.m</p>
  
  <pre><code>-(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;
  }
  </code></pre>
  
  <p>So basically the timer should continue when the application is in the background (it will send an alert based on the calculated times). That means the timer should continue when you click back and retap the cells. The reason it's not doing this is because everytime I tap a cell (or row), the DetailViewController gets allocated. I'm not sure how to fix this so I can save the times and start/pause as I like.</p>