做项目中经常会遇到秒杀、抢商品啊等等。那么这个十分秒的倒数是如何代码实现的呢!
通常后台会给我们一个时间戳活着截至日期(deadLine)。那么无论是时间戳还是一个具体的日期时间点,我们的处理逻辑都是这样的。统一处理成NSDate对象,那么就起名叫做endDate吧。我们还有一个开始时间,就是当前时间,命名为startDate。
我们要取到endDate和startDate的间隔有多久,有多长的时间间隔。那么废话少说,开始看代码,这样更清晰。
//结束时间
detailedDict[@”endTime”]为服务端返回的数据。
NSDateFormatter *dateFormatter=[[NSDateFormatter alloc] init];
if ([detailedDict[@”endTime”] length]==10) {
[dateFormatter setDateFormat:@”yyyy-MM-dd”];
}else{
[dateFormatter setDateFormat:@”yyyy-MM-dd HH:mm:ss”];
}
// NSDate *endDate = [dateFormatter dateFromString:detailedDict[@”endTime”]];
NSDate *endDate = [dateFormatter dateFromString:@”2016-02-20”];
那么这里注意了,如果后台给你的是这样的具体日期,那么我们还要多加一天的时间,毕竟要倒计时到 2016-02-20日的深夜0:00啊,下一秒就是2016-02-21日了。如果后台给的是时间戳,那么不用多加一天,因为时间戳就是个具体的时间点。
NSDate *endDate_tomorrow = [[NSDate alloc] initWithTimeIntervalSinceReferenceDate:([endDate timeIntervalSinceReferenceDate] + 24*3600)];
//当前时间
NSDate *startDate = [NSDate date];
//得到相差秒数
NSTimeInterval timeInterval =[endDate_tomorrow timeIntervalSinceDate:startDate];
下面处理UI显示的逻辑
if (timeInterval==0) {
detailCell.yzImageView.hidden = NO;
过期了,倒计时结束了
}else{
detailCell.yzImageView.hidden = YES;
没过期, 倒计时还会继续
}
这里用到这个 dispatch_source_t _timer;
把timer定义为全局的。
if (_timer==nil) {
__block int timeout = timeInterval; //倒计时时间
if (timeout!=0) {
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,queue);
dispatch_source_set_timer(_timer,dispatch_walltime(NULL, 0),1.0*NSEC_PER_SEC, 0); //每秒执行
dispatch_source_set_event_handler(_timer, ^{
if(timeout<=0){ //倒计时结束,关闭
dispatch_source_cancel(_timer);
_timer = nil;
dispatch_async(dispatch_get_main_queue(), ^{
detailCell.dayLabel.text = @"";
detailCell.hourLabel.text = @"00";
detailCell.minuteLabel.text = @"00";
detailCell.secondLabel.text = @"00";
detailCell.yzImageView.hidden = NO;
});
}else{
int days = (int)(timeout/(3600*24));
if (days==0) {
detailCell.dayLabel.text = @"";
}
int hours = (int)((timeout-days*24*3600)/3600);
int minute = (int)(timeout-days*24*3600-hours*3600)/60;
int second = timeout-days*24*3600-hours*3600-minute*60;
dispatch_async(dispatch_get_main_queue(), ^{
if (days==0) {
detailCell.dayLabel.text = @"";
}else{
detailCell.dayLabel.text = [NSString stringWithFormat:@"%d天",days];
}
if (hours<10) {
detailCell.hourLabel.text = [NSString stringWithFormat:@"0%d",hours];
}else{
detailCell.hourLabel.text = [NSString stringWithFormat:@"%d",hours];
}
if (minute<10) {
detailCell.minuteLabel.text = [NSString stringWithFormat:@"0%d",minute];
}else{
detailCell.minuteLabel.text = [NSString stringWithFormat:@"%d",minute];
}
if (second<10) {
detailCell.secondLabel.text = [NSString stringWithFormat:@"0%d",second];
}else{
detailCell.secondLabel.text = [NSString stringWithFormat:@"%d",second];
}
});
timeout--;
}
});
dispatch_resume(_timer);
}
}
上面的时间分别显示为 00天 3:35:49
天 时:分:秒
用四个UILabel分开来显示。因为我们可以算出时间间隔所对应的天、时、分、秒。然后每秒赋值一次就可以了。
每次进来这个页面都是从服务器获取最新的endDate进行倒计时。这样保证前端和后台的数据一致。
另外博主维护一个iOS开发技术支持群:479259423,进群必须改名,群名片格式:城市-iOS-名字,例如广州-iOS-文明。