Implementation of iOS MS countdown

App development, when the display of certain commodities limited time, often add a countdown, prompting the user to limit the time limit for the commodity,. For developers, this requires us to achieve is a countdown function, according to the specific needs of this countdown can be days, hours, minutes, seconds, milliseconds as a unit.

Today, I’m talking about millisecond timer. We know that the number of seconds and milliseconds is 1000, that is, a second =1000 MS, then we do the countdown timer is set to a time interval of 1 milliseconds of the timer, one by one to reduce the number of milliseconds. But it’s too time-consuming, so the number of milliseconds in the millisecond timer lot just between 0-9 numbers, which means that the millisecond timer interval is 100 milliseconds, so compared to 1 millisecond intervals of the timer, it consumes a lot less, but also achieve the effect of millisecond time.

For the whole millisecond countdown to the realization of ideas is: get the timestamp timestamp of a future date and the current date, calculate the time difference between the two, and then set a time interval of 100 ms timer, every 100 milliseconds, but the corresponding numerical update timer.

Customize a UIview, the countdown package.
a, in the MsecCountDownView.h to increase the time stamp and timer these two attributes

@interface MsecCountDownView: UIView @property (nonatomic, assign) double timeInterval; / / @property timestamp for a future date (nonatomic, strong) NSTimer *timer; / / @end timer

Two, in MsecCountDownView.m to achieve the relevant UI and countdown method

@interface MsecCountDownView (UIView) {*countdownBackView}; CGFloat _passTime; @property (nonatomic, strong) UILabel *tipLabel @property (nonatomic, strong); UILabel *hoursLabel; @property (nonatomic, strong) UILabel * minutesLabel; @property (nonatomic, strong) UILabel *secondsLabel @property (nonatomic, strong); UILabel *millionSecondsLabel; @property (nonatomic, strong) UILabel *label1; @property (nonatomic, strong) UILabel *label2; @ property (nonatomic, strong) UILabel *label3 @property (nonatomic, strong); UILabel *label4; @end

Create related UI

- (instancetype) initWithFrame: (CGRect frame) {self = [super initWithFrame:frame]; if (self) {countdownBackView=[[UIView alloc] initWithFrame:CGRectMake (0, 0, self.frame.size.width, self.frame.size.height)]; [self addSubview: countdownBackView]; _tipLabel=[[UILabel alloc] init]; _tipLabel.frame = CGRectMake (0, 0, 40, countdownBackView.frame.size.height); [countdownBackView addSubview:_tipLabel]; _tipLabel.font = [UIFont / systemFontOfSize:12]; _hoursLabel=[[UILabel alloc] initWithFrame:CGRectMake hours (_tipLabel.frame.origin.x+_tipLabel.frame.size.width, 0, 35, countdownBackView.frame.size.height); [countdownBackView addSubview:_hoursLabel]; _hour SLabel.font = [UIFont systemFontOfSize:11]; _label1=[[UILabel alloc] initWithFrame:CGRectMake (_hoursLabel.frame.origin.x+_hoursLabel.frame.size.width, _hoursLabel.frame.origin.y, 8, countdownBackView.frame.size.height); [countdownBackView addSubview:_label1]; _minutesLabel=[[UILabel alloc] initWithFrame:CGRectMake (_label1.frame.origin.x+_label1.frame.size.width / min, _hoursLabel.frame.origin.y, 20, countdownBackView.frame.size.height); [countdownBackView addSubview: _minutesLabel]; _minutesLabel.font = [UIFont systemFontOfSize:11]; _label2=[[UILabel alloc] initWithFrame:CGRectMake (_minutesLabel.frame.origin.x+_minutesLabel.frame.size.width, _hoursLabel.frame.origin.y, 8, cou NtdownBackView.frame.size.height)]; [countdownBackView addSubview:_label2]; _secondsLabel=[[UILabel alloc] initWithFrame:CGRectMake / / (_label2.frame.origin.x+_label2.frame.size.width, _hoursLabel.frame.origin.y, 20, countdownBackView.frame.size.height); [countdownBackView addSubview:_secondsLabel]; _secondsLabel.font = [UIFont systemFontOfSize:11]; _label3=[[UILabel alloc] initWithFrame:CGRectMake (_secondsLabel.frame.origin.x+_secondsLabel.frame.size.width, _hoursLabel.frame.origin.y, 8, countdownBackView.frame.size.height); [countdownBackView addSubview:_label3]; _millionSecondsLabel=[[UILabel alloc] initWithFrame:CGRectMake (_label3.frame.origin.x+_label3.frame.s Ize.width, _hoursLabel.frame.origin.y, 20, countdownBackView.frame.size.height); [countdownBackView addSubview:_millionSecondsLabel]; _millionSecondsLabel.font = [UIFont / MS systemFontOfSize:11]; _label1.textAlignment=1; _label2.textAlignment=1; _label3.textAlignment = 1; _hoursLabel.textAlignment=1; _minutesLabel.textAlignment=1; _secondsLabel.textAlignment=1; _millionSecondsLabel.textAlignment=1; _passTime=0.0 return self;}};

Create a timer

/ / get the time stamp a future date, compared with the current timestamp, the time difference, generation Timer - (void) setTimeInterval: (double timeInterval) {_timeInterval = timeInterval; NSDateFormatter = *dataFormatter [[NSDateFormatter alloc] init]; dataFormatter.dateFormat = @ "MM/dd/yyyy HH:mm:ss.SSS"; / / get the current system time, and use the corresponding [dataFormatter stringFromDate:[NSDate date]] NSString format conversion; *currentDayStr = [dataFormatter stringFromDate:[NSDate date]]; NSDate *currentDate = [dataFormatter dateFromString:currentDayStr]; / / preferential end time, also used the same format to convert NSDate *date = [NSDate dateWithTimeIntervalSince1970:timeInterval/1000.0]; NSString *deadline Str = [dataFormatter stringFromDate:date]; NSDate *deadlineDate = [dataFormatter dateFromString:deadlineStr]; _timeInterval=[deadlineDate timeIntervalSinceDate:currentDate]*1000; if (_timeInterval! =0) {/ / time interval is 100 milliseconds, which is 0.1 seconds _timer = [NSTimer scheduledTimerWithTimeInterval:0.1f target:self selector:@selector (timerAction) userInfo:nil repeats:YES]; [[NSRunLoop currentRunLoop] addTimer:_timer forMode:UITrackingRunLoopMode];}else{[countdownBackView removeFromSuperview];}}

To achieve the implementation of the method every 100 milliseconds, update the countdown timer the corresponding values

/ / every 100 millisecond timer trigger the execution of the method - (void) timerAction {[self getTimeFromTimeInterval:_timeInterval]; / / when the time interval is 0. When the timer if (_timeInterval-_passTime = = 0) {[_timer invalidate]; _timer = nil;}} / / through the calculation of the specific time interval of time (hours, minutes, seconds, milliseconds - (void) getTimeFromTimeInterval (double)): timeInterval {//1s=1000 MS _passTime + = 100.f; / / the number of milliseconds from 0-9, so every time in the past 100 ms [email protected] "left"; [email protected] "." [email protected] ";; [email protected]: *hours = NSString; / / the number of hours of"%ld ", [NSString stringWithFormat:@ ((timeInterval-_passTime (NSInteger) /1000/60/60)]); / / the number of minutes * NSString Minute = "%ld", [NSString stringWithFormat:@ (NSInteger) (/1000/60%60] (timeInterval-_passTime)); / / NSString *second [NSString stringWithFormat:@ the number of seconds = "%ld", ((NSInteger) /1000%60] (timeInterval-_passTime)); / / the number of milliseconds (SSS = CGFloat (NSInteger) ((timeInterval - _passTime)))%1000/100; NSString = *ss [NSString stringWithFormat:@ "%.lf" sss]; if (minute.integerValue < 10) {minute = "0%@" [NSString stringWithFormat:@, minute] self.hoursLabel.text [NSString stringWithFormat:@;} = "% @", hours]; self.minutesLabel.text = [NSString, minute]; stringWithFormat:@ "% @" self.secondsLabel.text = [NSString, second]; stringWithFormat:@ "% @" self.millionSecondsLabel.text = [NSString "% @ stringWithFormat:@ ", ss]; if (timeInterval - _passTime < = 0) {[countdownBackView removeFromSuperview]; [self removeFromSuperview];}}

Three, in the ViewController.m countdown timer assigned to achieve their desired countdown

- (void) viewDidLoad [super msecView=[[MsecCountDownView alloc] {viewDidLoad]; initWithFrame:CGRectMake (50, 100, self.view.frame.size.width-100, 16)]; [self.view addSubview:msecView]; NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateStyle:NSDateFormatterMediumStyle]; [formatter setTimeStyle:NSDateFormatterShortStyle]; [formatter setDateFormat:@ "yyyy-MM-dd HH:mm:ss.SSS"]; NSDate* date = [formatter dateFromString:@ "2017-04-11 15:10:00.000"]; / / date will be converted into time NSInteger timeSp = [[NSNumber numberWithDouble:[date timeIntervalSince1970]]. IntegerValue]*1000; msecView.timeInterval=timeSp;}

This will achieve the countdown function. But the use of countdown also need to pay attention to a little, when leaving the page, remember to pause the timer, and so on back to the page and then start countdown. This can be achieved by the following two methods.

- (void) viewWillAppear: (BOOL) animated{/ / page, open the timer [msecView.timer setFireDate:[NSDate distantPast]];} - (void) viewWillDisappear: (BOOL) animated{/ / page disappeared, prompting device [msecView.timer setFireDate:[NSDate suspended distantFuture]];}
If necessary, you can click on the GitHub to download demo

Demo