首页 > 其他分享 >OC 倒计时圆环

OC 倒计时圆环

时间:2024-01-27 20:46:11浏览次数:21  
标签:timeLabel bgLayer CAShapeLayer self OC 倒计时 shapeLayer countdownTimer 圆环

 

 

@interface SHMaasPTOnlineCarMatchmakingCircleCountdownView : UIView
@property (nonatomic, assign) NSInteger countdownDuration; // 倒计时总秒数
@property (nonatomic, assign) NSInteger currentCountdown; // 当前剩余秒数
@property (nonatomic, strong) UILabel *timeLabel; // 显示倒计时的标签
- (void)startCountdownFrom:(NSInteger)initialSeconds;
///取消倒计时
- (void)cancelCountdown;
@end

  

 

@interface SHMaasPTOnlineCarMatchmakingCircleCountdownView()
@end

@implementation SHMaasPTOnlineCarMatchmakingCircleCountdownView {
    UIBezierPath *_circlePath;
    CAShapeLayer *_circleLayer;
    CAShapeLayer *_bgLayer;
    dispatch_source_t _countdownTimer;
    dispatch_source_t _countdownTimer2;
}

- (void)drawRect:(CGRect)rect{
    [super drawRect:rect];
}

- (instancetype)init {
    self = [super init];
    if (self) {
//        self.backgroundColor = UIColor.redColor;

        // 添加时间标签
        _timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, 30)];
        _timeLabel.center = CGPointMake(self.frame.size.width / 2, self.frame.size.height / 2);
        _timeLabel.textColor = [UIColor colorWithHexString:@"#121612"];
        _timeLabel.font = [UIFont systemFontOfSize:16 weight:(UIFontWeightMedium)];
        _timeLabel.textAlignment = NSTextAlignmentCenter;
        [self addSubview:_timeLabel];
        [_timeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
            make.center.equalTo(self);
        }];
    }
    return self;
}

- (void)addLayer{

    UIBezierPath *path = [UIBezierPath bezierPath];
    // 添加一个半圆形(以view的中心为圆心)
    CGFloat radius = MIN(self.bounds.size.width, self.bounds.size.height) / 2;
    ///设置起始点 为顶部
    [path addArcWithCenter:self.center radius:radius startAngle: 1.5 * M_PI endAngle: 3.5 * M_PI clockwise:YES];
    
    ///灰色背景CAShapeLayer
    CAShapeLayer  *bgLayer  =  [CAShapeLayer  layer];
    bgLayer.frame  =  self.bounds;
    bgLayer.strokeEnd  =  1.0;//结束点
    bgLayer.strokeStart  =  0.0;//开始点
    bgLayer.path  =  path.CGPath;
    bgLayer.fillColor = [UIColor clearColor].CGColor; //Layer 的填充色
    bgLayer.lineWidth  =  5.0f;//宽度
    bgLayer.strokeColor  =  [UIColor  colorWithHexString:@"#DCDDE0"].CGColor;//边框色
    //将CAShaperLayer放到某个层上显示
    [self.layer  addSublayer:bgLayer];
    
    ///绿色CAShapeLayer
    CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    shapeLayer.frame = self.bounds;
//    shapeLayer.strokeEnd  =  1.0;//结束点
//    shapeLayer.strokeStart  =  0.0;//开始点
    shapeLayer.path = path.CGPath;
    shapeLayer.fillColor = [UIColor clearColor].CGColor;//Layer 的填充色
    shapeLayer.lineCap = kCALineCapRound;///圆角
    shapeLayer.lineWidth = 5.0f;//宽度
    shapeLayer.strokeColor = [UIColor colorWithHexString:@"#33A634"].CGColor;//边框色
    [self.layer addSublayer:shapeLayer];
    
    ///绿色CAShapeLayer 添加 动画
    CABasicAnimation *pathAnima = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    pathAnima.duration = 5.0f;//动画时间
    pathAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    pathAnima.fromValue = [NSNumber numberWithFloat:0.0f];//开始点
    pathAnima.toValue = [NSNumber numberWithFloat:1.0f];//结束点
    pathAnima.fillMode = kCAFillModeForwards;
    pathAnima.removedOnCompletion = NO;
    [shapeLayer addAnimation:pathAnima forKey:@"strokeEndAnimation"];
}
    
- (void)startCountdownFrom:(NSInteger)initialSeconds {
    [self addLayer];
    [self setNeedsDisplay];
    _countdownDuration = initialSeconds + 0.5;///有时差,
    __weak typeof(self) weakSelf = self;
    
    _currentCountdown = _countdownDuration;
    _countdownTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
    dispatch_source_set_timer(_countdownTimer, DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC, 0 * NSEC_PER_SEC); // 每秒更新一次
    dispatch_source_set_event_handler(_countdownTimer, ^{
        weakSelf.currentCountdown-= 1;
        [weakSelf updateTimeLabel];
        if (weakSelf.currentCountdown <= 0) {
            dispatch_source_cancel(self->_countdownTimer);
            // 倒计时结束后的处理
        }
    });
    dispatch_resume(_countdownTimer);
}

- (void)cancelCountdown {
    if (_countdownTimer) {
        dispatch_source_cancel(_countdownTimer);
        _countdownTimer = nil;
    }
    _currentCountdown = _countdownDuration; // 取消后重置为初始值
    [self updateTimeLabel]; // 更新时间标签显示为初始值
//    _circleLayer.strokeEnd = 1.0; // 清除环形进度条填充
}

- (void)updateTimeLabel {
    NSInteger minutes = _currentCountdown / 60;
    NSInteger seconds = _currentCountdown % 60;
    _timeLabel.text = [NSString stringWithFormat:@"%02ld:%02ld", (long)minutes, (long)seconds];
}

@end

  

参考:

https://www.jianshu.com/p/887c9afadb02

标签:timeLabel,bgLayer,CAShapeLayer,self,OC,倒计时,shapeLayer,countdownTimer,圆环
From: https://www.cnblogs.com/qingzZ/p/17991895

相关文章

  • 无涯教程-Socket.IO - 应用示例
    创建一个名为app.js的文件,然后输入以下代码来设置快速应用程序-varapp=require('express')();varhttp=require('http').Server(app);app.get('/',function(req,res){res.sendfile('index.html');});http.listen(3000,function(){conso......
  • curl支持ssl报错:(60) SSL certificate problem: unable to get local issuer certific
     curl去访问https的站点报错:curl-vhttps://www.baidu.com*SSLv3,TLShandshake,Clienthello(1):*SSLv3,TLShandshake,Serverhello(2):*SSLv3,TLShandshake,CERT(11):*SSLv3,TLSalert,Serverhello(2):*SSLcertificateproblem:unabletogetl......
  • 无涯教程-Socket.IO - 环境
    要开始使用Socket.IO进行开发,您需要安装Node和npm(节点程序包管理器)。如果您没有这些,请转到节点设置,以在本地系统上安装节点。通过在终端中运行以下命令来确认已安装节点和npm。node--versionnpm--version您应该得到类似于以下内容的输出:v17.3.08.3.0打开终端,并在......
  • 无涯教程-Socket.IO - 简介
    Socket.IO是用于实时Web应用程序的JavaScript库。它支持Web客户端和服务器之间的实时双向通信。它包括两个部分:在浏览器中运行的客户端库和用于node.js的服务器端库,这两个组件具有相同的API。实时应用实时应用程序(RTA)是在用户感知为即时或当前的时段内运行的应用程序。实......
  • ZooKeeper's atomic broadcast protocol:Theory and practice 翻译
    ZooKeeper’satomicbroadcastprotocol:TheoryandpracticeZooKeeper的原子广播协议:理论和实践Andr´eMedeirosMarch20,2012Abstract摘要ApacheZooKeeperisadistributedcoordinationserviceforcloudcomputing,providingessentialsynchronizationandgrou......
  • Docker 完整指南
    欢迎来到Docker的完整指南!在这个教程中,我们将深入研究Docker的各种特性,从基础的容器操作到高级的网络配置和数据管理。让我们一步步地探索Docker的丰富功能。1.安装Docker首先,确保您已经在系统上安装了Docker。可以在Docker官方网站上找到适用于您操作系统的安装说......
  • spring IOC DI 容器杂谈
    IOC容器的原理spring 博客收藏参考博客https://mp.weixin.qq.com/s?__biz=MzI4Njg5MDA5NA==&mid=2247484247&idx=1&sn=e228e29e344559e469ac3ecfa9715217&chksm=ebd74256dca0cb40059f3f627fc9450f916c1e1b39ba741842d91774f5bb7f518063e5acf5a0#rdhttps://www.zhihu.c......
  • SpringBoot中使用LocalDateTime踩坑记录
    目录前言近日心血来潮想做一个开源项目,目标是做一款可以适配多端、功能完备的模板工程,包含后台管理系统和前台系统,开发者基于此项目进行裁剪和扩展来完成自己的功能开发。本项目基于Java21和SpringBoot3开发,序列化工具使用的是默认的Jackson,使用SpringDataRedis操作Redis缓......
  • Leetcocde 1092. 最短公共超序列
    https://leetcode.cn/problems/shortest-common-supersequence/description/给你两个字符串str1和str2,返回同时以str1和str2作为子序列的最短字符串。如果答案不止一个,则可以返回满足条件的任意一个答案。如果从字符串t中删除一些字符(也可能不删除),可以得到字符串s......
  • filebeat整合docker
    1、新建filebeat.yml的配置文件用于指定Filebeat如何收集和传输日志数据。filebeat.inputs:-type:dockerenabled:truecontainers.ids:-"*"output.elasticsearch:hosts:["your-elasticsearch-host:9200"] 2、 创建DockerCompose文件version:"3"......