首页 文章

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

提问于
浏览
4

我有一个使用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 回答

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

相关问题