user2393702 user2393702 - 4 months ago 12
iOS Question

How can I make a countdown from the current date to a specific NSDate?

I want to have a countdown from the current time to a specific date and display that value in a label. I looked at some NSTimer tutorials but I could not figure out how to apply them to my situation.

NSTimeInterval TimeInterval = [aString doubleValue];
NSDate* upperDate = [aDate dateByAddingTimeInterval:TimeInterval];
NSDate* Today = [NSDate date];

//cell.myLabel.text = here i should write a countdown.


Sorry for insufficient code. I usually try to write some of my own code before asking a question here but this time I could not figure what to write.

Edit
So with the answer of PartiallyFinite i figured how i set timer. But because i am using tableview i could not implement the repeat message for MyTimerLabel. Here what i just did:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"MyCell";
MekanListesiViewCell *cell = (MyCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"MyCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}


aClass *aC = [myArray objectAtIndex:indexPath.row];
NSTimeInterval TimeInterval = [aC.aTimeIntervalwithString doubleValue];
NSDate* UpperDate = [aC.aNSDate dateByAddingTimeInterval:TimeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"YYYY-MM-dd"];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSUInteger unitFlags = NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit|NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit;
NSDateComponents *dateComponents = [calendar components:unitFlags fromDate:[NSDate date] toDate:UpperDate options:0];
NSInteger days = [dateComponents day];
NSInteger months = [dateComponents month];
NSInteger years = [dateComponents year];
NSInteger hours = [dateComponents hour];
NSInteger minutes = [dateComponents minute];
NSInteger seconds = [dateComponents second];
NSString *countdownText = [NSString stringWithFormat:@"%d Days %d:%d:%d", days, hours, minutes, seconds];
cell.countdownText= countdownText;
[self performSelector:@selector(updateCoundown)]; // The delay is in seconds, make it whatever you want.


return cell;
}
At myCellView.h
@interface MekanListesiViewCell : UITableViewCell
@property (nonatomic, weak) IBOutlet UILabel *MyTimerLabel;
@property(weak)NSString *countdownText;
at myCellView.m

-(void)updateCoundown{

MyTimerLabel.text = countdownText;
[self performSelector:@selector(updateCoundown) withObject:nil afterDelay:1];
}


i get nothing in the MyTimerLabel.

Answer

Using the code from this answer (copy pasted below for completeness of example) to get the individual components of the countdown period:

- (void)updateCountdown {
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"YYYY-MM-dd"];
    NSDate *startingDate = [dateFormatter dateFromString:@"2005-01-01"];
    NSDate *endingDate = [NSDate date];

    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSUInteger unitFlags = NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit|NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit;
    NSDateComponents *dateComponents = [calendar components:unitFlags fromDate:startingDate toDate:endingDate options:0];

    NSInteger days     = [dateComponents day];
    NSInteger months   = [dateComponents month];
    NSInteger years    = [dateComponents year];
    NSInteger hours    = [dateComponents hour];
    NSInteger minutes  = [dateComponents minute];
    NSInteger seconds  = [dateComponents second];

We can then create a string with all of these numbers:

    NSString *countdownText = [NSString stringWithFormat:@"%d Years %d Months %d Days %d Hours %d Minutes %d Seconds", days, months, years, hours, minutes, seconds];
    cell.myLabel.text = countdownText;

Then, we can use performSelector:withObject:afterDelay: to make this method get called again after the specified delay (note that the delay is in seconds):

    [self performSelector:@selector(updateCountdown) withObject:nil afterDelay:1];
}
Comments