2015-01-13 4 views
2

저는 CAShapeLayer를 사용하여 그려진 원호를 원 중심에서 회전시키고 싶습니다. 'transform.rotation'속성에 CABasicAnimation을 사용하여이 애니메이션을 가져 오려고합니다. 그러나 회전은 원의 중심과 같지 않은 지점에서 일어난 것처럼 보입니다. CABasicAnimation을 사용하여 CAShapeLayer 호를 중심으로 회전

enter image description here

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

나는 그에게 오래된 문제를 알고 있지만 무슨 방법 알아. 레이어의 경계 또는 앵커 포인트를 설정하여 많은 문제가 발생했지만 아직 센터를 중심으로 회전하지 않습니다.

circle.bounds = self.frame; 

다음은보기 컨트롤러에보기를 추가하는 방법입니다.

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

답변

2

이것은 결국 내가 한 것입니다. 실수는 레이어가 아닌 하위 레이어에 애니메이션을 추가하는 것이 었습니다. 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"]; } 
0

생각해이 같은)

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

스위프트 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") 
관련 문제