#import <Foundation/Foundation.h>
[@protocol](https://my.oschina.net/u/819710) TimeCountDownDelegate
@optional
//显示倒计时
- (void)showTime:(NSInteger)atime;
[@end](https://my.oschina.net/u/567204)
[@interface](https://my.oschina.net/u/996807) TimeCountDown : NSObject
{
NSTimer *aTimer;
//计时器间隔
NSTimeInterval aTimeInterval;
id<TimeCountDownDelegate> delegate;
NSInteger timecount;
}
[@property](https://my.oschina.net/property) (nonatomic,strong) id<TimeCountDownDelegate> delegate;
@property (nonatomic,assign) NSInteger timecount;
//传入时间是秒
- (void)setTimeInterval:(NSInteger)interval anddelegaate:(id)adeletage;
+(TimeCountDown *)sharedRegisterTimeCountDown;
+(TimeCountDown *)sharedResetpasswordTimeCountDown;
- (void)showTime;
@end
#import "TimeCountDown.h"
@implementation TimeCountDown
@synthesize delegate;
@synthesize timecount;
static TimeCountDown * registerTimeCountDown = nil;
static TimeCountDown * resetPasswordTimeCountDown = nil;
- (id)init
{
if(self = [super init])
{
timecount = 0;
}
return self;
}
- (void)startTime {
aTimer = [NSTimer scheduledTimerWithTimeInterval:aTimeInterval target:self selector:@selector(showTime) userInfo:nil repeats:YES];
}
- (void)stopTime {
[aTimer invalidate];
aTimer = nil;
}
- (void)setTimeInterval:(NSInteger)interval anddelegaate:(id)adeletage
{
if (timecount <= 0) {
timecount = interval;
self.delegate = adeletage;
aTimeInterval = 1;
[self startTime];
}
}
+(TimeCountDown *)sharedRegisterTimeCountDown
{
@synchronized(self)
{
if (registerTimeCountDown == nil) {
registerTimeCountDown = [[TimeCountDown alloc] init];
}
}
return registerTimeCountDown;
}
+(TimeCountDown *)sharedResetpasswordTimeCountDown
{
@synchronized(self)
{
if (resetPasswordTimeCountDown == nil) {
resetPasswordTimeCountDown = [[TimeCountDown alloc] init];
}
}
return resetPasswordTimeCountDown;
}
- (void)showTime
{
timecount--;
if (timecount >= 0) {
if (self.delegate) {
[self.delegate showTime:timecount];
}
}else{
[self stopTime];
}
}
@end
//调用
#import "ViewController.h"
#import "TimeCountDown.h"
#define MESSAGE_COUNTDOWN 10
@interface ViewController ()<TimeCountDownDelegate>
@property (nonatomic,strong) TimeCountDown * timeCountDown;
@property (nonatomic,strong) UIButton *messageBtn;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.messageBtn];
self.timeCountDown = [TimeCountDown sharedRegisterTimeCountDown];
_timeCountDown.delegate = self;
}
-(void)messageSendBtnTapped:(id) btn{
[self.timeCountDown setTimeInterval:MESSAGE_COUNTDOWN anddelegaate:self];
}
#pragma mark-SearchTime
- (void)showTime:(NSInteger)atime
{
if (self.timeCountDown.timecount > 0) {
[self.messageBtn setTitle:[NSString stringWithFormat:@"%td秒",atime] forState:UIControlStateNormal];
self.messageBtn.userInteractionEnabled = NO;
}else{
[self.messageBtn setTitle:@"获取" forState:UIControlStateNormal];
self.messageBtn.userInteractionEnabled = YES;
}
}
-(UIButton *)messageBtn{
if (!_messageBtn){
_messageBtn = [[UIButton alloc]init];
_messageBtn.frame = CGRectMake(100, 100, 50, 50);
[_messageBtn setTitle:@"获取" forState:UIControlStateNormal];
_messageBtn.layer.cornerRadius = 3.0f;
_messageBtn.clipsToBounds = YES;
_messageBtn.titleLabel.font = [UIFont boldSystemFontOfSize:16];
[_messageBtn setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];
[_messageBtn addTarget:self
action:@selector(messageSendBtnTapped:)
forControlEvents:UIControlEventTouchUpInside];
}
return _messageBtn;
}
@end

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface CountDown : NSObject
///用NSDate日期倒计时
-(void)countDownWithStratDate:(NSDate *)startDate finishDate:(NSDate *)finishDate completeBlock:(void (^)(NSInteger day,NSInteger hour,NSInteger minute,NSInteger second))completeBlock;
///用时间戳倒计时
-(void)countDownWithStratTimeStamp:(long long)starTimeStamp finishTimeStamp:(long long)finishTimeStamp completeBlock:(void (^)(NSInteger day,NSInteger hour,NSInteger minute,NSInteger second))completeBlock;
///每秒走一次,回调block
-(void)countDownWithPER_SECBlock:(void (^)())PER_SECBlock;
-(void)destoryTimer;
-(NSDate *)dateWithLongLong:(long long)longlongValue;
@end
#import "CountDown.h"
@interface CountDown ()
@property(nonatomic,retain) dispatch_source_t timer;
@property(nonatomic,retain) NSDateFormatter *dateFormatter;
@end
@implementation CountDown
- (instancetype)init{
self = [super init];
if (self) {
self.dateFormatter=[[NSDateFormatter alloc] init];
[self.dateFormatter setDateFormat:@"YYYY-MM-dd HH:mm:ss"];
NSTimeZone *localTimeZone = [NSTimeZone localTimeZone];
[self.dateFormatter setTimeZone:localTimeZone];
}
return self;
}
-(void)countDownWithStratDate:(NSDate *)startDate finishDate:(NSDate *)finishDate completeBlock:(void (^)(NSInteger day,NSInteger hour,NSInteger minute,NSInteger second))completeBlock{
if (_timer==nil) {
NSTimeInterval timeInterval =[finishDate timeIntervalSinceDate:startDate];
__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(), ^{
completeBlock(0,0,0,0);
});
}else{
int days = (int)(timeout/(3600*24));
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(), ^{
completeBlock(days,hours,minute,second);
});
timeout--;
}
});
dispatch_resume(_timer);
}
}
}
-(void)countDownWithPER_SECBlock:(void (^)())PER_SECBlock{
if (_timer==nil) {
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, ^{
dispatch_async(dispatch_get_main_queue(), ^{
PER_SECBlock();
});
});
dispatch_resume(_timer);
}
}
-(NSDate *)dateWithLongLong:(long long)longlongValue{
long long value = longlongValue/1000;
NSNumber *time = [NSNumber numberWithLongLong:value];
//转换成NSTimeInterval,用longLongValue,防止溢出
NSTimeInterval nsTimeInterval = [time longLongValue];
NSDate *date = [[NSDate alloc] initWithTimeIntervalSince1970:nsTimeInterval];
return date;
}
-(void)countDownWithStratTimeStamp:(long long)starTimeStamp finishTimeStamp:(long long)finishTimeStamp completeBlock:(void (^)(NSInteger day,NSInteger hour,NSInteger minute,NSInteger second))completeBlock{
if (_timer==nil) {
NSDate *finishDate = [self dateWithLongLong:finishTimeStamp];
NSDate *startDate = [self dateWithLongLong:starTimeStamp];
NSTimeInterval timeInterval =[finishDate timeIntervalSinceDate:startDate];
__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(), ^{
completeBlock(0,0,0,0);
});
}else{
int days = (int)(timeout/(3600*24));
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(), ^{
completeBlock(days,hours,minute,second);
});
timeout--;
}
});
dispatch_resume(_timer);
}
}
}
/**
* 获取当天的年月日的字符串
* @return 格式为年-月-日
*/
-(NSString *)getNowyyyymmdd{
NSDate *now = [NSDate date];
NSDateFormatter *formatDay = [[NSDateFormatter alloc] init];
formatDay.dateFormat = @"yyyy-MM-dd";
NSString *dayStr = [formatDay stringFromDate:now];
return dayStr;
}
/**
* 主动销毁定时器
* @return 格式为年-月-日
*/
-(void)destoryTimer{
if (_timer) {
dispatch_source_cancel(_timer);
_timer = nil;
}
}
-(void)dealloc{
NSLog(@"%s dealloc",object_getClassName(self));
}
@end
//
// CountDownViewController.m
// 倒计时
//
// Created by Maker on 16/7/5.
// Copyright © 2016年 郑文明. All rights reserved.
//
#import "CountDownViewController.h"
#import "Masonry.h"
#import "UIView+ArrangeSubview.h"
#import "CountDown.h"
@interface CountDownViewController ()
@property (strong, nonatomic) UILabel *dayLabel;
@property (strong, nonatomic) UILabel *hourLabel;
@property (strong, nonatomic) UILabel *minuteLabel;
@property (strong, nonatomic) UILabel *secondLabel;
@property (strong, nonatomic) UIView *contentView;
@property (strong, nonatomic) UIButton *timeBtn;
@property (strong, nonatomic) CountDown *countDownForBtn;
@property (strong, nonatomic) CountDown *countDownForLabel;
@end
@implementation CountDownViewController
/**
* 获取当天的年月日的字符串
* 这里测试用
* @return 格式为年-月-日
*/
-(NSString *)getyyyymmdd{
NSDate *now = [NSDate date];
NSDateFormatter *formatDay = [[NSDateFormatter alloc] init];
formatDay.dateFormat = @"yyyy-MM-dd";
NSString *dayStr = [formatDay stringFromDate:now];
return dayStr;
}
///布局UI
-(void)initUI{
CGFloat label_width = 60;
CGFloat label_Height = 40;
self.contentView = [UIView new];
self.contentView.backgroundColor = [UIColor magentaColor];
[self.view addSubview:self.contentView];
[self.contentView mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(4*label_width, label_Height));
make.center.equalTo(self.view);
}];
self.dayLabel = [UILabel new];
self.dayLabel.textAlignment = NSTextAlignmentCenter;
self.dayLabel.backgroundColor = [UIColor cyanColor];
self.dayLabel.font = [UIFont systemFontOfSize:15];
[self.contentView addSubview:self.dayLabel];
self.hourLabel = [UILabel new];
self.hourLabel.textAlignment = NSTextAlignmentCenter;
self.hourLabel.font = [UIFont systemFontOfSize:15];
self.hourLabel.backgroundColor = [UIColor greenColor];
[self.contentView addSubview:self.hourLabel];
self.minuteLabel = [UILabel new];
self.minuteLabel.textAlignment = NSTextAlignmentCenter;
self.minuteLabel.font = [UIFont systemFontOfSize:15];
self.minuteLabel.backgroundColor = [UIColor redColor];
[self.contentView addSubview:self.minuteLabel];
self.secondLabel = [UILabel new];
self.secondLabel.textAlignment = NSTextAlignmentCenter;
self.secondLabel.font = [UIFont systemFontOfSize:15];
self.secondLabel.backgroundColor = [UIColor orangeColor];
[self.contentView addSubview:self.secondLabel];
[self.dayLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(@[self.hourLabel,self.minuteLabel,self.secondLabel]);
make.top.equalTo(self.contentView);
make.width.mas_equalTo(label_width);
make.height.equalTo(self.contentView);
}];
[self.hourLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.equalTo(self.dayLabel);
}];
[self.minuteLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.equalTo(self.dayLabel);
}];
[self.secondLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.equalTo(self.dayLabel);
}];
[self.contentView arrangeSubviewWithSpacingHorizontally:@[self.dayLabel,self.hourLabel,self.minuteLabel,self.secondLabel]];
self.timeBtn = [UIButton buttonWithType:UIButtonTypeCustom];
self.timeBtn.backgroundColor = [UIColor redColor];
[self.timeBtn setTitle:@"点击获取验证码" forState:UIControlStateNormal];
[self.timeBtn addTarget:self action:@selector(fetchCoder:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.timeBtn];
[self.timeBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(self.contentView);
make.left.mas_equalTo(self.contentView);
make.bottom.mas_equalTo(self.contentView.mas_top).offset(-40);
}];
UIButton *nextPageBtn = [UIButton buttonWithType:UIButtonTypeCustom];
nextPageBtn.backgroundColor = [UIColor redColor];
[nextPageBtn setTitle:@"push到下一页" forState:UIControlStateNormal];
[nextPageBtn addTarget:self action:@selector(nextPage:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:nextPageBtn];
[nextPageBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(self.timeBtn);
make.left.mas_equalTo(self.timeBtn);
make.bottom.mas_equalTo(self.timeBtn.mas_top).offset(-40);
}];
}
-(void)nextPage:(UIButton *)sender{
UIViewController *aVC = [[UIViewController alloc]init];
aVC.view.backgroundColor = [UIColor whiteColor];
[self.navigationController pushViewController:aVC animated:YES];
}
-(void)fetchCoder:(UIButton *)sender{
// 60s的倒计时
// NSTimeInterval aMinutes = 60;
// 1个小时的倒计时
// NSTimeInterval anHour = 60*60;
// 1天的倒计时
NSTimeInterval aDay = 24*60*60;
[self startWithStartDate:[NSDate date] finishDate:[NSDate dateWithTimeIntervalSinceNow:aDay]];
}
#pragma mark
#pragma mark viewDidLoad
- (void)viewDidLoad {
[super viewDidLoad];
[self initUI];
self.view.backgroundColor = [UIColor whiteColor];
_countDownForLabel = [[CountDown alloc] init];
_countDownForBtn = [[CountDown alloc] init];
///方法一倒计时测试
long long startLongLong = 1467713971000;
// long long finishLongLong = 1467714322000;
long long finishLongLong = 1467755322000;
[self startLongLongStartStamp:startLongLong longlongFinishStamp:finishLongLong];
NSDateFormatter* formater = [[NSDateFormatter alloc] init];
[formater setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSDate* startDate = [formater dateFromString:@"2018-12-31 08:23:20"];
NSDate* finishDate = [formater dateFromString:@"2019-1-1 00:00:00"];
// [self startWithStartDate:startDate finishDate:finishDate];
}
-(void)refreshUIDay:(NSInteger)day hour:(NSInteger)hour minute:(NSInteger)minute second:(NSInteger)second{
if (day==0) {
self.dayLabel.text = @"0天";
}else{
self.dayLabel.text = [NSString stringWithFormat:@"%ld天",(long)day];
}
if (hour<10&&hour) {
self.hourLabel.text = [NSString stringWithFormat:@"0%ld小时",(long)hour];
}else{
self.hourLabel.text = [NSString stringWithFormat:@"%ld小时",(long)hour];
}
if (minute<10) {
self.minuteLabel.text = [NSString stringWithFormat:@"0%ld分",(long)minute];
}else{
self.minuteLabel.text = [NSString stringWithFormat:@"%ld分",(long)minute];
}
if (second<10) {
self.secondLabel.text = [NSString stringWithFormat:@"0%ld秒",(long)second];
}else{
self.secondLabel.text = [NSString stringWithFormat:@"%ld秒",(long)second];
}
}
///此方法用两个时间戳做参数进行倒计时
-(void)startLongLongStartStamp:(long long)strtLL longlongFinishStamp:(long long)finishLL{
__weak __typeof(self) weakSelf= self;
[_countDownForLabel countDownWithStratTimeStamp:strtLL finishTimeStamp:finishLL completeBlock:^(NSInteger day, NSInteger hour, NSInteger minute, NSInteger second) {
NSLog(@"666");
[weakSelf refreshUIDay:day hour:hour minute:minute second:second];
}];
}
//此方法用两个NSDate对象做参数进行倒计时
-(void)startWithStartDate:(NSDate *)strtDate finishDate:(NSDate *)finishDate{
__weak __typeof(self) weakSelf= self;
[_countDownForBtn countDownWithStratDate:strtDate finishDate:finishDate completeBlock:^(NSInteger day, NSInteger hour, NSInteger minute, NSInteger second) {
NSLog(@"second = %li",second);
NSInteger totoalSecond =day*24*60*60+hour*60*60 + minute*60+second;
if (totoalSecond==0) {
weakSelf.timeBtn.enabled = YES;
[weakSelf.timeBtn setTitle:@"重新获取验证码" forState:UIControlStateNormal];
}else{
weakSelf.timeBtn.enabled = NO;
[weakSelf.timeBtn setTitle:[NSString stringWithFormat:@"%lis后重新获取",totoalSecond] forState:UIControlStateNormal];
}
}];
}
-(void)dealloc{
[_countDownForLabel destoryTimer];
[_countDownForBtn destoryTimer];
NSLog(@"%s dealloc",object_getClassName(self));
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end