使用CABasicAnimation围绕其中心旋转CAShapeLayer弧

时间:2015-01-13 03:14:59

标签: core-animation calayer

我有一个使用CAShapeLayer绘制的弧线,我希望它围绕圆圈的中心旋转。我试图在' transform.rotation'上使用CABasicAnimation来获取此动画。属性。但轮换似乎正在发生与圈子中心不同的一点。

-(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"];
} 

enter image description here

我知道这是一个老问题,但最终会有什么问题。我通过设置图层的边界或锚点来修改很多东西,但它还没有围绕中心旋转。

circle.bounds = self.frame;

以下是我将视图添加到视图控制器的方法。

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

2 个答案:

答案 0 :(得分:5)

这是我最终做的。 错误是将动画添加到子图层而不是图层。 当只需要围绕圆心时需要旋转时,无需修改anchorPoint或位置。

- (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"]; }

答案 1 :(得分:2)

认为最好做这样的事情)

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];

动画:

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")