倒计时(时分秒)面板

Posted iOS的美丽岁月

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了倒计时(时分秒)面板相关的知识,希望对你有一定的参考价值。

场景

最近公司App的UI 页面更新,出现了一个项目倒计时面板。该倒计时是用于计时项目到开放还剩余多少时间。效果如下:



分析上图

上图粉红色我标记的地方是倒计时的面板样式,我们把该样式看成10块元素组成。这10块元素如下:“距离项目上线还有:”、“0”、“9”、“小时”、“3”、“0”、“分”、“1”、“1”、“秒”。至于为什么要把时、分、秒的十位和个位分开,你看面板样式你就应该理解了。


使用到的的知识点

-  计算动态计算UILable 的宽度。

-  给UILable描边和切角。

-  定时器的使用(开始&暂停)。

-  定时器在默认的RunLoop中,当页面有滑动定时器不计时。

-  时间的进制转化。

-  求余数的知识。

-  时间戳的转换知识。


倒计时面板类


1、初始化10个元素。

-(instancetype)initWithFrame:(CGRect)frame
    if (self == [super initWithFrame:frame]) 
        //  初始化
        lable1 = [UILabel new];
        lable1.textAlignment = NSTextAlignmentCenter ;
        lable1.textColor = [UIColor colorWithDisplayP3Red:113/255.0 green:113/255.0 blue:113/255.0 alpha:1.0];
        [self addSubview:lable1];
        hoursTenLable = [UILabel new];
        hoursTenLable.textAlignment = NSTextAlignmentCenter ;
        hoursTenLable.font = [UIFont systemFontOfSize:15];
        [self addSubview:hoursTenLable];
        hoursBitsLable = [UILabel new];
        hoursBitsLable.textAlignment = NSTextAlignmentCenter ;
        hoursBitsLable.font = [UIFont systemFontOfSize:15];
        [self addSubview:hoursBitsLable];
        lable2 = [UILabel new];
        lable2.textAlignment = NSTextAlignmentCenter ;
        lable2.textColor = [UIColor colorWithDisplayP3Red:113/255.0 green:113/255.0 blue:113/255.0 alpha:1.0];
        [self addSubview:lable2];
        minutesTenLable = [UILabel new];
        minutesTenLable.textAlignment = NSTextAlignmentCenter ;
        minutesTenLable.font = [UIFont systemFontOfSize:15];
        [self addSubview:minutesTenLable];
        minutesBitsLable = [UILabel new];
        minutesBitsLable.textAlignment = NSTextAlignmentCenter ;
        minutesBitsLable.font = [UIFont systemFontOfSize:15];
        [self addSubview:minutesBitsLable];
        lable3 = [UILabel new];
        lable3.textAlignment = NSTextAlignmentCenter ;
        lable3.textColor = [UIColor colorWithDisplayP3Red:113/255.0 green:113/255.0 blue:113/255.0 alpha:1.0];
        [self addSubview:lable3];
        secondsTenLable = [UILabel new];
        secondsTenLable.textAlignment = NSTextAlignmentCenter ;
        secondsTenLable.font = [UIFont systemFontOfSize:15];
        [self addSubview:secondsTenLable];
        secondsBitsLable = [UILabel new];
        secondsBitsLable.textAlignment = NSTextAlignmentCenter ;
        secondsBitsLable.font = [UIFont systemFontOfSize:15];
        [self addSubview:secondsBitsLable];
        lable4 = [UILabel new];
        lable4.textAlignment = NSTextAlignmentCenter ;
        lable4.textColor = [UIColor colorWithDisplayP3Red:113/255.0 green:113/255.0 blue:113/255.0 alpha:1.0];
        [self addSubview:lable4];
    
    return self;


2、10个元素的布局

#pragma mark 布局
-(void)layoutSubviews
    // 文字一
    CGFloat lable1Wide = [self calculateLableWide:lable1];
    lable1.frame = CGRectMake(0, 0, lable1Wide, Height);
    // 小时十位
    CGFloat hoursWide = [self calculateLableWide:hoursTenLable];
    hoursTenLable.layer.borderColor = [UIColor lightGrayColor].CGColor;
    hoursTenLable.layer.borderWidth = 0.5 ;
    hoursTenLable.layer.cornerRadius = cornerRadius ;
    hoursTenLable.frame = CGRectMake(CGRectGetMaxX(lable1.frame), 0, hoursWide+deviation, (hoursWide+deviation)*4/3);
    hoursTenLable.center = CGPointMake(hoursTenLable.center.x, lable1.center.y);
    // 小时个位
    CGFloat hoursBits = [self calculateLableWide:hoursBitsLable];
    hoursBitsLable.layer.borderColor = [UIColor lightGrayColor].CGColor;
    hoursBitsLable.layer.borderWidth = 0.5 ;
    hoursBitsLable.layer.cornerRadius = cornerRadius ;
    hoursBitsLable.frame = CGRectMake(CGRectGetMaxX(hoursTenLable.frame)+ TenMinDeviation, 0, hoursBits + deviation, (hoursBits+deviation)*4/3);
    hoursBitsLable.center = CGPointMake(hoursBitsLable.center.x, lable1.center.y);
    // 文字二
    CGFloat lable2Wide = [self calculateLableWide:lable2];
    lable2.frame = CGRectMake(CGRectGetMaxX(hoursBitsLable.frame), 0, lable2Wide, Height);
    // 分十位
    CGFloat minutesWide = [self calculateLableWide:minutesTenLable];
    minutesTenLable.layer.borderColor = [UIColor lightGrayColor].CGColor;
    minutesTenLable.layer.borderWidth = 0.5 ;
    minutesTenLable.layer.cornerRadius = cornerRadius ;
    minutesTenLable.frame = CGRectMake(CGRectGetMaxX(lable2.frame), 0, minutesWide + deviation, (minutesWide+deviation)*4/3);
    minutesTenLable.center = CGPointMake(minutesTenLable.center.x, lable1.center.y);
    // 分个位
    CGFloat minutesBits = [self calculateLableWide:minutesBitsLable];
    minutesBitsLable.layer.borderColor = [UIColor lightGrayColor].CGColor;
    minutesBitsLable.layer.borderWidth = 0.5 ;
    minutesBitsLable.layer.cornerRadius = cornerRadius ;
    minutesBitsLable.frame = CGRectMake(CGRectGetMaxX(minutesTenLable.frame)+ TenMinDeviation, 0, minutesBits + deviation, (minutesBits+deviation)*4/3);
    minutesBitsLable.center = CGPointMake(minutesBitsLable.center.x, lable1.center.y);
    // 文字三
    CGFloat lable3Wide = [self calculateLableWide:lable3];
    lable3.frame = CGRectMake(CGRectGetMaxX(minutesBitsLable.frame), 0, lable3Wide, Height);
    // 秒十位
    CGFloat secondsWide = [self calculateLableWide:secondsTenLable];
    secondsTenLable.layer.borderColor = [UIColor lightGrayColor].CGColor;
    secondsTenLable.layer.borderWidth = 0.5 ;
    secondsTenLable.layer.cornerRadius = cornerRadius ;
    secondsTenLable.frame = CGRectMake(CGRectGetMaxX(lable3.frame), 0, secondsWide + deviation, (secondsWide+deviation)*4/3);
    secondsTenLable.center = CGPointMake(secondsTenLable.center.x, lable1.center.y);
    // 秒个位
    CGFloat secondsBits = [self calculateLableWide:secondsBitsLable];
    secondsBitsLable.layer.borderColor = [UIColor lightGrayColor].CGColor;
    secondsBitsLable.layer.borderWidth = 0.5 ;
    secondsBitsLable.layer.cornerRadius = cornerRadius ;
    secondsBitsLable.frame = CGRectMake(CGRectGetMaxX(secondsTenLable.frame)+ TenMinDeviation, 0, secondsBits + deviation, (secondsBits+deviation)*4/3);
    secondsBitsLable.center = CGPointMake(secondsBitsLable.center.x, lable1.center.y);
    // 文字四
    CGFloat lable4Wide = [self calculateLableWide:lable4];
    lable4.frame = CGRectMake(CGRectGetMaxX(secondsBitsLable.frame), 0, lable4Wide, Height);

    self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, CGRectGetMaxX(lable4.frame), self.bounds.size.height);


3、 当面版添加到分类View上的时候的处理。

-(void)willMoveToSuperview:(UIView *)newSuperview
    hoursTenValue = hoursTenLable.text.intValue;
    hoursBitsValue = hoursBitsLable.text.intValue;
    minutesBitsValue = minutesBitsLable.text.intValue;
    minutesTenValue = minutesTenLable.text.intValue;
    secondsTenValue = secondsTenLable.text.intValue;
    secondsBitsValue = secondsBitsLable.text.intValue;
    timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(countDownMethod) userInfo:nil repeats:YES];
    // 解决由于滑动造成定时器不计时的问题
    [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];


4、定时器时间的处理。

#pragma mark 时间处理事件
-(void)countDownMethod
    // 判断是否结束
    if (hoursTenValue == 0 && hoursBitsValue==0 && minutesTenValue == 0 && minutesBitsValue == 0 && secondsTenValue == 0 && secondsBitsValue == 0) 
        //[timer invalidate];
    
    if (hoursBitsValue==0 && minutesTenValue ==0 && minutesBitsValue == 0 && secondsTenValue == 0 && secondsBitsValue == 0) 
        hoursTenValue -- ;
        hoursBitsValue = 9 ;
        minutesTenValue = 5 ;
        minutesBitsValue = 9 ;
        secondsTenValue = 5 ;
        secondsBitsValue = 10 ;
    
    if(minutesTenValue ==0 && minutesBitsValue == 0 && secondsTenValue == 0 && secondsBitsValue == 0)
        hoursBitsValue -- ;
        minutesTenValue = 5 ;
        minutesBitsValue = 9 ;
        secondsTenValue = 5 ;
        secondsBitsValue = 10 ;
    
    if (minutesBitsValue == 0 && secondsTenValue == 0 && secondsBitsValue == 0) 
        minutesTenValue--;
        minutesBitsValue = 9 ;
        secondsTenValue = 5 ;
        secondsBitsValue = 10 ;
    
    if (secondsTenValue == 0 && secondsBitsValue == 0) 
        minutesBitsValue -- ;
        secondsTenValue = 5 ;
        secondsBitsValue = 10 ;
    
    if (secondsBitsValue == 0) 
        secondsTenValue--;
        secondsBitsValue = 10 ;
    
    if (secondsBitsValue != 0) 
        secondsBitsValue -- ;
    
    hoursTenLable.text = [NSString stringWithFormat:@"%ld",(long)hoursTenValue];
    hoursBitsLable.text = [NSString stringWithFormat:@"%ld",(long)hoursBitsValue];
    secondsTenLable.text = [NSString stringWithFormat:@"%ld",(long)secondsTenValue];
    secondsBitsLable.text = [NSString stringWithFormat:@"%ld",(long)secondsBitsValue];
    minutesTenLable.text = [NSString stringWithFormat:@"%ld",(long)minutesTenValue];
    minutesBitsLable.text = [NSString stringWithFormat:@"%ld",(long)minutesBitsValue];


5、计算UILable的宽度

#pragma mark 计算文字的宽
-(CGFloat)calculateLableWide:(UILabel*)lable
    CGRect rect = [lable.text boundingRectWithSize:CGSizeMake(self.bounds.size.width, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes: @NSFontAttributeName:lable.font,NSForegroundColorAttributeName:lable.textColor context:nil];
    return rect.size.width ;



6、时间戳差转化成时分秒

// 计算两个时间的差值
-(NSArray*)getHMS:(NSString*)timeString1 withTimeStamp:(NSString*)timeString2 timeDateFormat:(NSString*)dateFormat
    // 判断两个值是否存在
    if (timeString1==nil && timeString2==nil) 
        return nil;
    
    // 设置时间转化的格式
    NSDateFormatter *  formatter  = [[NSDateFormatter alloc]init];
    if (dateFormat==nil) 
        dateFormat = @"YYYY-MM-dd HH:mm:ss";
    
    [formatter setDateFormat:dateFormat];
    // 将字符串转化成时间的数据
    NSDate * date1 = [formatter dateFromString:timeString1];
    NSDate * date2 = [formatter dateFromString:timeString2];
    // 再将时间数据转化成时间戳
    NSTimeInterval  timeStamp1 = [date1 timeIntervalSince1970];
    NSTimeInterval  timeStamp2 = [date2 timeIntervalSince1970];
    // 再计算两个时间的差值
    NSTimeInterval timeStampdiff = ABS(timeStamp2 - timeStamp1);
    // 时、分、秒的参数
    int hours = 0 ,minutes = 0 , second = 0 ,day = 0;
    // 计算各个的取值
    second = (int)timeStampdiff % 60 ;
    minutes = (int)timeStampdiff / 60 % 60;
    hours = (int)timeStampdiff / 3600;
    day = (int)timeStampdiff / (24 * 3600);
    NSMutableArray * mutableArray = [NSMutableArray array];
    // 计算结果的输出
    hours = hours + day * 24 ;
    if (hours>=10) 
        [mutableArray addObject:@(hours/10)];
        [mutableArray addObject:@(hours%10)];
    
    [mutableArray addObject:@(0)];
    [mutableArray addObject:@(hours%10)];
    if (minutes>=10) 
        [mutableArray addObject:@(minutes/10)];
        [mutableArray addObject:@(minutes%10)];
    
    [mutableArray addObject:@(0)];
    [mutableArray addObject:@(minutes%10)];
    if (second>=10) 
        [mutableArray addObject:@(second/10)];
        [mutableArray addObject:@(second%10)];
    
    [mutableArray addObject:@(0)];
    [mutableArray addObject:@(second%10)];
    // 返回输出结果
    return mutableArray ;




倒计时面板类的使用

// 设置
CountdownView * downView = [[CountdownView alloc]initWithFrame:CGRectMake(0, 100, self.view.bounds.size.width, 40)];
downView->lable1.text = @"距离项目上线还有:";
downView->hoursTenLable.text = @"2";
downView->hoursBitsLable.text = @"3";
downView->lable2.text = @"小时";
downView->minutesTenLable.text = @"5";
downView->minutesBitsLable.text = @"8";
downView->lable3.text = @"分";
downView->secondsTenLable.text = @"5";
downView->secondsBitsLable.text = @"0";
downView->lable4.text = @"秒";
[self.view addSubview:downView];


效果展示






以上是关于倒计时(时分秒)面板的主要内容,如果未能解决你的问题,请参考以下文章

基于51单片机通过点击移位按键移位修改LCD1602字符型液晶显示器显示时分秒个位十位数值的计时项目工程

js简单时分秒倒计时

时分秒 分别用啥字母表示

倒计时时分秒

JS 倒计时实现代码(时分,秒)

js简单时分秒倒计时