Rotating a CAShapeLayer arc about its center using CABasicAnimation

I have an arc that I have drawn using CAShapeLayer and I want it to rotate around the circle's center. I am trying to get this animation using a CABasicAnimation on the 'transform.rotation' property. But the rotation seems is happening about a point that is not the same as the circle's center.

-(void)drawRect:(CGRect)rect{
 int radius = 100;
 CAShapeLayer *circle = [CAShapeLayer layer];
 circle.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 2.0*radius, 2.0*radius) cornerRadius:radius].CGPath;
 circle.fillColor = [UIColor orangeColor].CGColor;
 circle.strokeColor = [UIColor blueColor].CGColor;
 circle.lineWidth = 5;
 circle.strokeStart = 0.0f;
 circle.strokeEnd = 0.1f;
 [self.layer addSublayer:circle];

 CABasicAnimation *spinAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
 spinAnimation.byValue = [NSNumber numberWithFloat:2.0f*M_PI];
 spinAnimation.duration = 4;
 spinAnimation.repeatCount = INFINITY;
 [circle addAnimation:spinAnimation forKey:@"indeterminateAnimation"];
} 

在这里输入图像描述

I know its an old problem, but whats the way out. I have tinkered a lot by setting the layer's bounds or the anchor point but it doesn't rotate about the center yet.

circle.bounds = self.frame;

Here is how I add the view to the view controller.

[self.view addSubview:[[ProgressIndicator alloc] initWithFrame:CGRectMake(50, 50, 200, 200)]];

This is what I eventually did. The mistake was to add the animation to the sublayer and not the layer. There is no need to tinker with anchorPoint or position here when the rotation is just needed about the center of the circle.

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
       self.backgroundColor = [UIColor clearColor];

       int radius = 50;
       CAShapeLayer *circle = [CAShapeLayer layer];
       circle.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 2.0*radius, 2.0*radius) cornerRadius:radius].CGPath;
       circle.fillColor = [UIColor clearColor].CGColor;
       circle.strokeColor = [UIColor blueColor].CGColor;
       circle.lineWidth = 5;
       circle.strokeStart = 0.0f;
       circle.strokeEnd = 0.1f;

       [self.layer addSublayer:circle];
    }

   return self; }

- (void)drawRect:(CGRect)rect {

    CABasicAnimation *spinAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
    spinAnimation.byValue = [NSNumber numberWithFloat:2.0f*M_PI];
    spinAnimation.duration = 4;
    spinAnimation.repeatCount = INFINITY;

    [self.layer addAnimation:spinAnimation forKey:@"indeterminateAnimation"]; }

Think is better to do something like this)

CGFloat center = CGRectGetWidth(frame) / 2;
CGFloat lineWidth = 5;
CGFloat radius = center - lineWidth / 2;
CGRect bounds = frame;
bounds.origin = CGPointZero;

CAShapeLayer *spinLayer = [CAShapeLayer layer];
spinLayer.path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(center, center) radius:radius startAngle:0 endAngle:0.2 clockwise:YES].CGPath;
spinLayer.fillColor = [UIColor clearColor].CGColor;
spinLayer.strokeColor = [UIColor blueColor].CGColor;
spinLayer.lineWidth = 5;
spinLayer.lineCap = kCALineCapRound;
spinLayer.bounds = bounds;
spinLayer.position = CGPointMake(center, center);
[self.layer insertSublayer:spinLayer above:nil];

And animation:

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
animation.byValue = [NSNumber numberWithFloat:2.f * M_PI];
animation.duration = 1.5f;
animation.repeatCount = INFINITY;
[spinLayer addAnimation:animation forKey:@"lineRotation"];
[self setNeedsLayout];

Swift 3

        var bounds = frame
        bounds.origin = CGPoint.zero
        let center: CGFloat = frame.size.width
        let lineWidth: CGFloat = 5
        let radius = center - lineWidth / 2

        let spinLayer = CAShapeLayer()
        spinLayer.path = UIBezierPath(arcCenter: CGPoint(x: center, y: center),
                                 radius: radius,
                                 startAngle: 0,
                                 endAngle: 0.2,
                                 clockwise: true).cgPath

        spinLayer.strokeColor = UIColor.blue.cgColor
        spinLayer.fillColor = UIColor.clear.cgColor
        spinLayer.lineWidth = lineWidth
        spinLayer.lineCap = kCALineCapRound
        spinLayer.bounds = bounds
        spinLayer.position = CGPoint(x: center, y: center)

        view.layer.insertSublayer(spinLayer, above: nil)

        let rotation = CABasicAnimation(keyPath: "transform.rotation")
        rotation.byValue = NSNumber(value: 2*M_PI as Double)
        rotation.duration = 1
        rotation.repeatCount = Float.infinity

        spinLayer.add(rotation, forKey: "lineRotation")
链接地址: http://www.djcxy.com/p/12882.html

上一篇: CAGradientLayer混淆了CATransform3DRotate

下一篇: 使用CABasicAnimation围绕其中心旋转CAShapeLayer弧