首页 > 解决方案 > 带有 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% 的动画着色。我可以改变它吗?我需要一个接一个地显示所有动画。(需要显示下载进度)

标签: iosobjective-cprogress-bar

解决方案


您需要删除下面这 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"];

}

结果

在此处输入链接描述


推荐阅读