字符串倒计时代码示例

//  AppDelegate.h

#import 
@interface AppDelegate : UIResponder 
@property (strong, nonatomic) UIWindow *window;
@end

//  AppDelegate.m

#import "AppDelegate.h"

@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    return YES;
}


- (void)applicationWillResignActive:(UIApplication *)application {
   
}


- (void)applicationDidEnterBackground:(UIApplication *)application {
    
    UIApplication *app = [UIApplication sharedApplication];
    __block UIBackgroundTaskIdentifier bgTask;
    bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
        dispatch_async(dispatch_get_main_queue(), ^{
            if (bgTask != UIBackgroundTaskInvalid) {
                bgTask = UIBackgroundTaskInvalid;
            }
        });
    }];
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        dispatch_async(dispatch_get_main_queue(), ^{
            if (bgTask != UIBackgroundTaskInvalid) {
                bgTask = UIBackgroundTaskInvalid;
            }
        });
    });
}


- (void)applicationWillEnterForeground:(UIApplication *)application {
    
}


- (void)applicationDidBecomeActive:(UIApplication *)application {
    
}


- (void)applicationWillTerminate:(UIApplication *)application {
    
}


@end


//  ViewController.h

#import 

@interface ViewController : UIViewController


@end


//  ViewController.m

#import "ViewController.h"
#import "CountDownManager.h"

@interface ViewController ()

@property (nonatomic, strong)UILabel *label;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [kCountDownManager start];//开始倒计时
    CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
    self.label = [[UILabel alloc]initWithFrame:CGRectMake((screenWidth - 300)/2, 300, 300, 100)];
    self.label.textColor = [UIColor greenColor];
    self.label.textAlignment = NSTextAlignmentCenter;
    self.label.numberOfLines = 0;
    [self.view addSubview:self.label];
    // 监听通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(countDownNotification) name:CountDownNotification object:nil];
    
}

- (NSString *)convertTimeIntervalToFormatDate:(NSTimeInterval)timeInterval {
    //初始时间格式化对象
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    //设置时间格式
    dateFormatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
    //时间戳转时间
    NSDate *date = [NSDate dateWithTimeIntervalSince1970:timeInterval];
    return [dateFormatter stringFromDate:date];
}

- (NSMutableAttributedString *)getCountdownAttributStringWithStringOne:(NSString *)stringOne stringTwo:(NSString *)stringTwo{
    NSString * str = [self convertTimeIntervalToFormatDate:1557973398];
    //初始化可变富文本对象
    NSMutableAttributedString *string1 = [[NSMutableAttributedString alloc]initWithString:stringOne];
    
    NSMutableAttributedString *string2 = [[NSMutableAttributedString alloc]initWithAttributedString:[self getNowTimeWithString:str]];
    
    NSMutableAttributedString *string3 = [[NSMutableAttributedString alloc]initWithString:stringTwo];
    //拼接属性化字符串
    [string1 appendAttributedString:string2];
    [string1 appendAttributedString:string3];
    //初始化可变的段落样式,用于设置首行,行间距,对齐方式等
    NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
    //设置字体的行间距
    [style setLineSpacing:1];
    [string1 addAttribute:NSParagraphStyleAttributeName value:style range:NSMakeRange(0, string1.length)];
    return string1;
}

- (NSAttributedString *)getNowTimeWithString:(NSString *)aTimeString {
    NSDateFormatter *formater = [[NSDateFormatter alloc] init];
    [formater setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSDate *expireDate = [formater dateFromString:aTimeString];
    NSDate *nowDate = [NSDate date];
    NSString *nowDateStr = [formater stringFromDate:nowDate];
    nowDate = [formater dateFromString:nowDateStr];
    //时间转时间戳
    NSTimeInterval timeInterval =[expireDate timeIntervalSinceDate:nowDate];
    //倒计时的计算
    int days = (int)(timeInterval/(3600*24));
    int hours = (int)((timeInterval-days*24*3600)/3600);
    int minutes = (int)(timeInterval-days*24*3600-hours*3600)/60;
    int seconds = timeInterval-days*24*3600-hours*3600-minutes*60;
    
    NSString *dayStr = nil;
    NSString *hoursStr = nil;
    NSString *minutesStr = nil;
    NSString *secondsStr = nil;
    dayStr = [NSString stringWithFormat:@"%d",days];
    hoursStr = [NSString stringWithFormat:@"%d",hours];
    
    if(minutes < 10) {
        minutesStr = [NSString stringWithFormat:@"0%d", minutes];
    } else {
        minutesStr = [NSString stringWithFormat:@"%d", minutes];
    }
    
    if(seconds < 10) {
        secondsStr = [NSString stringWithFormat:@"0%d", seconds];
    } else {
        secondsStr = [NSString stringWithFormat:@"%d", seconds];
    }
    
    if (hours <= 0 &&
        minutes <= 0 &&
        seconds <= 0) {
        //倒计时结束
        [kCountDownManager invalidate];
        NSString *nowTimeStr = @"0天0小时0分0秒";
         NSMutableAttributedString *attributeString  = [[NSMutableAttributedString alloc]initWithString:nowTimeStr];
        return attributeString;
    }
    NSString *nowTimeStr = [NSString stringWithFormat:@"%@ 天%@ 小时%@ 分%@ 秒", dayStr, hoursStr, minutesStr, secondsStr];
    NSMutableAttributedString *attributeString  = [[NSMutableAttributedString alloc]initWithString:nowTimeStr];
    //设置富文本颜色
    [attributeString setAttributes:@{NSForegroundColorAttributeName:[UIColor redColor]} range:NSMakeRange(0, nowTimeStr.length)];
    return attributeString;
}

-(NSDate *)DateFromTimeStamap:(NSString *)timeStamap{
    //传入的时间戳timeStamap如果是精确到毫秒要/1000
    NSTimeInterval timeInterval = [timeStamap doubleValue]/1000;
    NSDate *date = [NSDate dateWithTimeIntervalSince1970:timeInterval];
    return date;
}

- (void)countDownNotification {
    //赋值给label
    self.label.attributedText = [self getCountdownAttributStringWithStringOne:@"火箭还有" stringTwo:@"发射"];
}

-(void)dealloc{
    // 废除定时器
    [kCountDownManager invalidate];
    // 清空时间差
    [kCountDownManager reload];
}
@end


//  CountDownManager.h

#import 

/** 宏: 使用单例 */
#define kCountDownManager [CountDownManager manager]
/** 倒计时的通知名 */
extern NSString *const CountDownNotification;

@interface CountDownManager : NSObject

/** 使用单例 */
+ (instancetype)manager;

/** 开始倒计时 */
- (void)start;

/** 停止倒计时 */
- (void)invalidate;

// ======== v1.0 ========
// 如果只需要一个倒计时差, 可继续使用timeInterval属性
// 增加后台模式, 后台状态下会继续计算时间差

/** 时间差(单位:秒) */
@property (nonatomic, assign) NSInteger timeInterval;

/** 刷新倒计时(兼容旧版本, 如使用identifier标识的时间差, 请调用reloadAllSource方法) */
- (void)reload;



// ======== v2.0 ========
// 增加identifier:标识符, 一个identifier支持一个倒计时源, 有一个单独的时间差

/** 添加倒计时源 */
- (void)addSourceWithIdentifier:(NSString *)identifier;

/** 获取时间差 */
- (NSInteger)timeIntervalWithIdentifier:(NSString *)identifier;

/** 刷新倒计时源 */
- (void)reloadSourceWithIdentifier:(NSString *)identifier;

/** 刷新所有倒计时源 */
- (void)reloadAllSource;

/** 清除倒计时源 */
- (void)removeSourceWithIdentifier:(NSString *)identifier;

/** 清除所有倒计时源 */
- (void)removeAllSource;

@end

@interface OYTimeInterval : NSObject

@end


//  CountDownManager.m

#import "CountDownManager.h"
#import 

@interface OYTimeInterval ()

@property (nonatomic, assign) NSInteger timeInterval;

+ (instancetype)timeInterval:(NSInteger)timeInterval;

@end

@implementation OYTimeInterval

+ (instancetype)timeInterval:(NSInteger)timeInterval {
    OYTimeInterval *object = [OYTimeInterval new];
    object.timeInterval = timeInterval;
    return object;
}

@end

NSString *const CountDownNotification = @"CountDownNotification";

@interface CountDownManager()

@property (nonatomic, strong) NSTimer *timer;

/// 时间差字典(单位:秒)(使用字典来存放, 支持多列表或多页面使用)
@property (nonatomic, strong) NSMutableDictionary *timeIntervalDict;
/// 后台模式使用, 记录进入后台的绝对时间
@property (nonatomic, assign) BOOL backgroudRecord;
@property (nonatomic, assign) CFAbsoluteTime lastTime;

@end

@implementation CountDownManager

+ (instancetype)manager {
    static CountDownManager *manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [[CountDownManager alloc]init];
    });
    return manager;
}

- (instancetype)init {
    self = [super init];
    if (self) {
        // 监听进入前台与进入后台的通知
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidEnterBackgroundNotification) name:UIApplicationDidEnterBackgroundNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillEnterForegroundNotification) name:UIApplicationWillEnterForegroundNotification object:nil];
    }
    return self;
}

//开始倒计时
- (void)start {
    // 启动定时器
    [self timer];
}

//刷新倒计时
- (void)reload {
    // 刷新只要让时间差为0即可
    _timeInterval = 0;
}

//停止倒计时
- (void)invalidate {
    [self.timer invalidate];
    self.timer = nil;
}

- (void)timerAction {
    // 定时器每次加1
    [self timerActionWithTimeInterval:1];
}

- (void)timerActionWithTimeInterval:(NSInteger)timeInterval {
    // 时间差+
    self.timeInterval += timeInterval;
    [self.timeIntervalDict enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, OYTimeInterval * _Nonnull obj, BOOL * _Nonnull stop) {
        obj.timeInterval += timeInterval;
    }];
    // 发出通知
    [[NSNotificationCenter defaultCenter] postNotificationName:CountDownNotification object:nil userInfo:nil];
}

//添加倒计时源
- (void)addSourceWithIdentifier:(NSString *)identifier {
    OYTimeInterval *timeInterval = self.timeIntervalDict[identifier];
    if (timeInterval) {
        timeInterval.timeInterval = 0;
    }else {
        [self.timeIntervalDict setObject:[OYTimeInterval timeInterval:0] forKey:identifier];
    }
}

//获取时间差
- (NSInteger)timeIntervalWithIdentifier:(NSString *)identifier {
    return self.timeIntervalDict[identifier].timeInterval;
}

//刷新倒计时源
- (void)reloadSourceWithIdentifier:(NSString *)identifier {
    self.timeIntervalDict[identifier].timeInterval = 0;
}

//刷新所有倒计时源
- (void)reloadAllSource {
    [self.timeIntervalDict enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, OYTimeInterval * _Nonnull obj, BOOL * _Nonnull stop) {
        obj.timeInterval = 0;
    }];
}

//清除倒计时源
- (void)removeSourceWithIdentifier:(NSString *)identifier {
    [self.timeIntervalDict removeObjectForKey:identifier];
}

//清除所有倒计时源
- (void)removeAllSource {
    [self.timeIntervalDict removeAllObjects];
}

//接受到程序进入后台的回调方法
- (void)applicationDidEnterBackgroundNotification {
    self.backgroudRecord = (_timer != nil);
    if (self.backgroudRecord) {
        self.lastTime = CFAbsoluteTimeGetCurrent();
        [self invalidate];
    }
}

//接受到程序回到前台的回调方法
- (void)applicationWillEnterForegroundNotification {
    if (self.backgroudRecord) {
        CFAbsoluteTime timeInterval = CFAbsoluteTimeGetCurrent() - self.lastTime;
        // 取整
        [self timerActionWithTimeInterval:(NSInteger)timeInterval];
        [self start];
    }
}

//初始化定时器
- (NSTimer *)timer {
    if (_timer == nil) {
        _timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
        //RunLoop是一个对象,这个对象在循环中用来处理程序运行过程中出现的各种事件(比如说触摸事件、UI刷新事件、定时器事件、Selector事件),从而保持程序的持续运行;而且在没有事件处理的时候,会进入睡眠模式,从而节省CPU资源,提高程序性能。
        //[NSRunLoop mainRunLoop]获得主线程的RunLoop对象
        [[NSRunLoop mainRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
    }
    return _timer;
}

//可变字典懒加载
- (NSMutableDictionary *)timeIntervalDict {
    if (!_timeIntervalDict) {
        _timeIntervalDict = [NSMutableDictionary dictionary];
    }
    return _timeIntervalDict;
}

@end

开始倒计时


Untitled.gif

结束倒计时


屏幕快照 2019-05-15 下午11.13.46.png

你可能感兴趣的:(字符串倒计时代码示例)