封装了一个iOS对号成功动画

请添加图片描述

基本思路其实很简单,就是通过贝塞尔曲线画出路径,然后
使用CAShapeLayer 渲染路径,然后通过strokeEnd 动画实现
路径的效果,这里注意,这个过程中过遇到过一个问题,就是
对号动画完成之后,整个对号不见了,后来经过仔细调查,发现,是自己初始化 checkLayer的时候,将strokeEnd属设置为0了,注意,虽然我们是通过"strokeEnd"设置的动画,但是我们进行动画之后,并不会真正的改变layer.strokeEnd属性的值,所以我们初始化对号layer的时候,还是要将strokeEnd设置为1
下面贴出所有代码

//
//  ViewController.m
//  LBProgressCircle
//
//  Created by mac on 2024/5/31.
//#import "ViewController.h"@interface ViewController ()@property (nonatomic, strong) UIView *loadingView;//进度圆环曲线
@property (nonatomic, strong) UIBezierPath *circlePath;
//整个圆环
@property (nonatomic, strong) CAShapeLayer *wholeCircleLayer;
//进度圆环layer
@property (nonatomic, strong) CAShapeLayer *progressLayer;
//对号圆环
@property (nonatomic, strong) CAShapeLayer *checkRoundLayer;
//对号layer
@property (nonatomic, strong) CAShapeLayer *checkLayer;@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];self.view.backgroundColor = [UIColor lightGrayColor];[self.view addSubview:self.loadingView];[self.loadingView.layer addSublayer:self.wholeCircleLayer];[self.loadingView.layer addSublayer:self.progressLayer];[self.loadingView.layer addSublayer:self.checkLayer];[self.loadingView.layer addSublayer:self.checkRoundLayer];[self handle];// Do any additional setup after loading the view.
}- (void)handle
{self.progressLayer.strokeEnd = 0;__block CGFloat second = 0;NSTimer *time = [NSTimer scheduledTimerWithTimeInterval:0.1 repeats:YES block:^(NSTimer * _Nonnull timer) {if (second >= 1) {return;}second += 0.1;[self updateProgress:second];}];
}- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{[self handle];
}- (void)updateProgress:(CGFloat)progress
{self.progressLayer.strokeEnd = progress;if (progress >= 1) {[self showProgressCirce:NO];[self.checkRoundLayer addAnimation:[self animation] forKey:@"strokeEnd"];dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{self.checkLayer.hidden = NO;[self.checkLayer addAnimation:[self animation] forKey:@"strokeEnd"];});} else {self.checkLayer.hidden = YES;[self showProgressCirce:YES];}
}- (void)showProgressCirce:(BOOL)showCircle
{self.checkRoundLayer.hidden = showCircle;self.wholeCircleLayer.hidden = !showCircle;self.progressLayer.hidden = !showCircle;
}#pragma mark - lazy load- (UIView *)loadingView
{if (!_loadingView) {_loadingView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];_loadingView.backgroundColor = [UIColor blackColor];}return _loadingView;
}- (UIBezierPath *)circlePath
{if (!_circlePath) {_circlePath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(27.5, 44) radius:19 startAngle:-M_PI_2 endAngle:-M_PI_2 + M_PI * 2 clockwise:YES];_circlePath.lineCapStyle = kCGLineCapRound;_circlePath.lineJoinStyle = kCGLineJoinRound;}return _circlePath;
}- (CAShapeLayer *)progressLayer
{if (!_progressLayer) {_progressLayer = [[CAShapeLayer alloc] init];_progressLayer.path = self.circlePath.CGPath;_progressLayer.strokeStart = 0;_progressLayer.strokeEnd = 0;_progressLayer.strokeColor = [UIColor redColor].CGColor;_progressLayer.fillColor = [UIColor clearColor].CGColor;_progressLayer.lineWidth = 2;}return _progressLayer;
}- (CAShapeLayer *)wholeCircleLayer
{if (!_wholeCircleLayer) {_wholeCircleLayer = [[CAShapeLayer alloc] init];_wholeCircleLayer.path = self.circlePath.CGPath;_wholeCircleLayer.strokeStart = 0;_wholeCircleLayer.strokeEnd = 1;_wholeCircleLayer.strokeColor = [[UIColor redColor] colorWithAlphaComponent:0].CGColor;_wholeCircleLayer.fillColor = [UIColor clearColor].CGColor;_wholeCircleLayer.lineWidth = 2;}return _wholeCircleLayer;
}- (CAShapeLayer *)checkRoundLayer
{if (!_checkRoundLayer) {UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(27.5, 44) radius:16 startAngle:- M_PI_2 endAngle:- M_PI_2 + M_PI * 2 clockwise:YES];path.lineCapStyle = kCGLineCapRound;path.lineJoinStyle = kCGLineJoinRound;_checkRoundLayer = [[CAShapeLayer alloc] init];_checkRoundLayer.path = path.CGPath;_checkRoundLayer.strokeColor = [UIColor whiteColor].CGColor;_checkRoundLayer.fillColor = [UIColor clearColor].CGColor;_checkRoundLayer.hidden = YES;_checkRoundLayer.lineWidth = 2;}return _checkRoundLayer;
}- (CAShapeLayer *)checkLayer
{if (!_checkLayer) {UIBezierPath *path = [[UIBezierPath alloc] init];path.lineCapStyle = kCGLineCapRound;path.lineJoinStyle = kCGLineJoinRound;[path moveToPoint:CGPointMake(19, 43)];CGPoint pl = CGPointMake(25, 49);[path addLineToPoint:pl];CGPoint p2 = CGPointMake(36, 39);[path addLineToPoint:p2];_checkLayer = [[CAShapeLayer alloc] init];_checkLayer.fillColor = [UIColor clearColor].CGColor;//线条颜色_checkLayer.strokeColor = [UIColor whiteColor].CGColor;_checkLayer.lineWidth = 2;_checkLayer.path = path.CGPath;_checkLayer.hidden = YES;}return _checkLayer;
}- (CABasicAnimation *)animation
{CABasicAnimation *checkAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];checkAnimation.duration = 0.5;checkAnimation.fromValue = @(0);checkAnimation.toValue = @(1);return checkAnimation;
}@end

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/20032.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Superset二次开发之更新 SECRET_KEY

SECRET_KEY 的作用 加密和签名:SECRET_KEY用于对敏感数据(如会话、cookie、CSRF令牌)进行加密和签名,防止数据被篡改。安全性:确保应用的安全性,防止跨站请求伪造(CSRF)攻击和会话劫持等安全问题。如何生成 SECRET_KEY openssl rand -base64 42 配置 SECRET_KEY 在sup…

【主动均衡和被动均衡】

文章目录 1.被动均衡2.主动均衡1.被动均衡 被动均衡一般通过电阻放电的方式,对电压较高的电池进行放电,以热量形式释放电量,为其他电池争取更多充电时间。这样整个系统的电量受制于容量最少的电池。充电过程中,锂电池一般有一个充电上限保护电压值,当某一串电池达到此电压…

uniapp 添加字体ttf

效果图如下 一、逻辑概述 在uniapp中使用字体&#xff0c;一共分成两种情况&#xff0c;一种是普通vue页面&#xff0c;一种是nvue页面引入字体。。 1.vue页面引入字体需要如下步骤 1. 先选择下载一种字体&#xff1a;字体格式一般为 ttf后缀名 黄凯桦律师手写体免费下载和在线…

Linux--EXT2文件系统

参考资料&#xff1a; linux之EXT2文件系统--理解block/block group/索引结点inode/索引位图_一个块组中索引节点表和数据块区最多占用字节-CSDN博客 linux环境&#xff1a; Linux version 5.15.146.1-microsoft-standard-WSL2 (root65c757a075e2) (gcc (GCC) 11.2.0, GNU ld…

Java后端模拟面试 题集⑤

1.先作个自我介绍吧 面试官您好&#xff0c;我叫张睿超&#xff0c;来自湖南长沙&#xff0c;大学毕业于湖南农业大学&#xff0c;是一名智能科学与技术专业的统招一本本科生。今天主要过来面试贵公司的Java后端开发工程师岗位。 大学里面主修的课程是Java、Python、数字图像…

FreeRtos进阶——中断的内部逻辑

中断与非中断API的区别 BaseType_t xQueueSendToBack(QueueHandle_t xQueue,const void *pvItemToQueue,TickType_t xTicksToWait); BaseType_t xQueueSendToBackFromISR(QueueHandle_t xQueue,const void *pvItemToQueue,BaseType_t *pxHigherPriorityTaskWok…

MFC工控项目实例之二添加iPlotx控件

承接专栏《MFC工控项目实例之一主菜单制作》 在WIN10下使用Visual C 6.0 &#xff08;完整绿色版&#xff09;添加iPlotx控件的方法。 1、在资源主对话框界面点击鼠标右键如图选择插入Active控件点击进入。 2、选择iPlotx Contrlolh点击确定。 3、在对话框界面插入iPlotx控件。…

emp.dll文件丢失要怎么解决?荒野大镖客emp.dll修复方法分享

软件运行过程中经常遇到各种技术问题&#xff0c;其中之一就是动态链接库&#xff08;DLL&#xff09;文件丢失的现象。DLL文件是Windows操作系统中一个重要的组件&#xff0c;它包含运行多个应用程序所需要的代码和数据。因此&#xff0c;一个丢失的DLL文件&#xff0c;如“em…

《逆水寒》手游周年庆,热度不减反增引发热议

易采游戏网5月31日最新消息&#xff1a;随着数字娱乐时代的飞速发展&#xff0c;手游市场的竞争愈发激烈。在这样的大背景下&#xff0c;《逆水寒》手游以其独特的古风武侠世界和深度的社交体验&#xff0c;自上线以来便吸引了无数玩家的目光。如今&#xff0c;这款游戏迎来了它…

对象转为Map

方案一&#xff0c;Jackson String json objectMapperFace.writeValueAsString(contract);Map<String,Object> map objectMapperFace.readValue(json, Map.class);方案二 &#xff0c; apache BeanUtils Map<String,String> beanMap null;try {beanMap BeanUti…

MMrotate报错AttributeError: ‘NoneType‘ object has no attribute ‘shape‘

使用MMrotate训练自定义数据集报错&#xff1a; AttributeError: ‘NoneType’ object has no attribute ‘shape’ 2024-05-31 17:48:06,121 - mmrotate - INFO - workflow: [(train, 1)], max: 12 epochs 2024-05-31 17:48:06,121 - mmrotate - INFO - Checkpoints will be …

相同的树(oj题)

一、题目链接https://leetcxode-cn.com/problems/same-tree/ 二、题目思路 遍历整颗树&#xff0c;判断两棵树的每个位置的结点都相同。 每个结点的左右孩子结点都要综合判断 三、题解代码 bool isSameTree(struct TreeNode* p, struct TreeNode* q) {//如果两颗树的根结点…

汇舟问卷:国外问卷调查两小时赚28美金?

现在的年轻人不愿意打工的原因不只是因为累&#xff0c;而且赚的钱也不多。有些人开玩笑地说&#xff0c;摆个摊儿卖点小商品都比上班赚得多&#xff0c;这确实是事实。 打工只能勉强维持生计&#xff0c;不能致富。因此&#xff0c;如果我们想赚大钱&#xff0c;首先需要改变…

炫云亮相第二十届中国国际动漫节国际动漫游戏商务大会!

5月28日-29日&#xff0c;备受瞩目的第二十届中国国际动漫节国际动漫游戏商务大会(iABC2024)在杭州滨江开元名都大酒店隆重召开&#xff01;本届大会以动漫IP为核心&#xff0c;从源头到全系列数字内容&#xff0c;探索创新协同、融合发展、价值转化&#xff0c;并对重点作品和…

IDEA 常用技巧

1、代码块整体移动 选中&#xff0c;tab整体右移选中&#xff0c;shifttab整体左 移 2、统一修改变量 3.方法分割线 seting >> editor >> apperance >> show method separators 4、快捷键 构造器、set与get方法、方法重写、toString 等快捷操 鼠标停留在…

人工智能在消化道肿瘤中的最新研究【24年五月|顶刊速递·05-31】

小罗碎碎念 2024-05-31|医学AI顶刊速递 今天分享的六篇文章,主题是AI+结肠癌。但是,并非所有的文章都是直接与结直肠癌相关,比如第一篇研究的就是肝癌。 我其实想关注的是消化道肿瘤的医学AI研究——消化道由口腔、食管、胃、小肠、大肠和直肠组成,而肝脏虽然不直接参与食…

java海滨学院班级回忆录源码(springboot)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的海滨学院班级回忆录。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 海滨学院班级回忆录的…

运维开发.Kubernetes探针与应用

运维系列 Kubernetes探针与应用 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csdn.net/qq_28550263…

电商物流查询解决方案助力提升消费者体验

截至2023年12月&#xff0c;中国网络购物用户规模达9.15亿人&#xff0c;占网民整体的83.8%。这一庞大的数字不仅展现了电子商务的蓬勃发展&#xff0c;也标志着数字零售企业营销战略的转变——从以产品和流量为核心&#xff0c;到用户为王的新阶段。因此&#xff0c;提升消费者…

探索 Android Studio 中的 Gemini:加速 Android 开发的新助力

探索 Android Studio 中的 Gemini&#xff1a;加速 Android 开发的新助力 在 Gemini 时代的下一篇章中&#xff0c;Gemini融入了更多产品中&#xff0c;Android Studio 正在使用 Gemini 1.0 Pro 模型&#xff0c;使 Android 开发变得更快、更简单。 Studio Bot 现已更名为 And…