ios - 带有 CAShapeLayer 和 CABasicAnimation 的圆形进度条
问题描述
我正在尝试使用此处的想法制作循环进度视图
这是我的 CircleView 代码:
#import "CircleView.h"
@interface CircleView()
@property (nonatomic, strong) CAShapeLayer *circleLayer;
@end
@implementation CircleView
-(instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = UIColor.clearColor;
UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.frame.size.width / 2., self.frame.size.height / 2.0) radius: (self.frame.size.width - 10) / 2 startAngle:0.0 endAngle:M_PI * 2 clockwise:YES];
CAShapeLayer *downLayer = [[CAShapeLayer alloc] init];
downLayer.path = circlePath.CGPath;
downLayer.fillColor = UIColor.clearColor.CGColor;
downLayer.strokeColor = UIColor.lightGrayColor.CGColor;
downLayer.lineWidth = 10.0;
downLayer.strokeEnd = 1.0;
self.circleLayer = [[CAShapeLayer alloc] init];
self.circleLayer.path = circlePath.CGPath;
self.circleLayer.fillColor = UIColor.clearColor.CGColor;
self.circleLayer.strokeColor = UIColor.redColor.CGColor;
self.circleLayer.lineWidth = 10.0;
self.circleLayer.strokeEnd = 0.0;
[self.layer addSublayer:downLayer];
[self.layer addSublayer: self.circleLayer];
}
return self;
}
-(void)animateCircle:(NSTimeInterval)duration fromPart:(CGFloat)fromPart toPart: (CGFloat)toPart {
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
animation.duration = duration;
animation.fromValue = @(fromPart);
animation.toValue = @(toPart);
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
self.circleLayer.strokeEnd = toPart;
[self.circleLayer addAnimation:animation forKey:@"animateCircle"];
}
@end
问题是当我尝试多次制作这个动画时。然后它只显示上次调用的动画,就好像之前的调用已经完成动画一样。例如,如果我拨打以下两个电话:
[self.circleView animateCircle:1 fromPart:0.0 toPart:0.25];
[self.circleView animateCircle:1 fromPart:0.25 toPart:0.5];
它将仅显示从圆圈的 0.25% 到圆圈的 0.5% 的动画着色。我可以改变它吗?我需要一个接一个地显示所有动画。(需要显示下载进度)
解决方案
您需要删除下面这 2 行,它将按预期工作。
animation.fromValue = @(fromPart);
animation.toValue = @(toPart);
因为您用于显示下载进度,所以您的方法在动画圈时CircleView
不需要值。您可以像下面的代码一样fromPart
更新方法。animateCircle
-(void)animateCircle:(NSTimeInterval)duration toPart: (CGFloat)toPart {
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
animation.duration = duration;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
self.circleLayer.strokeEnd = toPart;
[self.circleLayer addAnimation:animation forKey:@"animateCircle"];
}
结果
推荐阅读
- c++ - 为什么需要在c++运算符重载中删除内存并分配新内存
- docker - 如何在 Docker Vault 容器中创建机密
- .net - 如何使用 msbuild 或 Roslyn 仅在给定项目中构建源代码?
- xamarin.forms - 在 listView 模板中更改 BindingContext 不指向 Viewmodel
- python - 需要在 Asyncio Loop 中运行 Playwright Sync API
- scheme - 考虑应用函数的简单方法
- java - 运行 fat jar vs sbt run
- arrays - mongodb如何只找到数组的一部分
- html - AEM富文本源编辑器锚标记剥离href形成如Sightly标记
- python - 根据输入(或自动输入)提取另一个值