沿弧线animationUIView

我希望沿着一个圆弧来创build一个视图,如位置1到位置2的图像所示。

在这里输入图像说明

实际情况是,视图animation描述了一个完整的圆而不是弧。 我的问题是:

  1. 我应该使用CGPathAddArc还是CGPathAddArcToPoint
  2. 我是否需要使用CGPathMoveToPoint来描述视图的初始位置?

当我遍历代码时,CGPoints值与我所预期的一样,angular度也一样。

我使用下面的函数在一个圆上获取CGPoints

CGPoint pointOnCircle(CGPoint centre, float radius, float angle) { float x = centre.x + radius * cosf(angle); float y = centre.y + radius * sinf(angle); return CGPointMake(x, y); } 

我正在使用下面的代码和其变体,但至今我还没有设法破解它。

 CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; pathAnimation.calculationMode = kCAAnimationPaced; pathAnimation.fillMode = kCAFillModeForwards; pathAnimation.removedOnCompletion = NO; pathAnimation.duration = duration; pathAnimation.repeatCount = 1; CGPoint viewCenter = dynamicView.objectCenter; CGMutablePathRef arcPath = CGPathCreateMutable(); // CGPathMoveToPoint(arcPath, NULL, viewCenter.x, viewCenter.y); //work out the half way point float halfwayAngle = dynamicView.angle + (0.5f * self.angleIncrement); float fullwayAngle = dynamicView.angle + self.angleIncrement; CGPoint halfwayPoint = pointOnCircle(self.center, self.radius, halfwayAngle); CGPoint fullwayPoint = pointOnCircle(self.center, self.radius, fullwayAngle); CGPathAddArc(arcPath, NULL, halfwayPoint.x, halfwayPoint.y, self.radius, dynamicView.angle, fullwayAngle, clockwise); // CGPathAddArcToPoint(arcPath, NULL, viewCenter.x, viewCenter.y, fullwayPoint.x, fullwayPoint.y, self.radius); pathAnimation.path = arcPath; CGPathRelease(arcPath); [dynamicView.layer addAnimation:pathAnimation forKey:@"arc"]; 

我编写了一个快速的例子,希望把它放在一起。 我从“单视图”应用程序模板开始,并将此操作与button一起添加到视图控制器以触发操作。

 - (IBAction)animateArc:(id)sender { // Create the arc CGPoint arcStart = CGPointMake(0.2 * self.view.bounds.size.width, 0.5 * self.view.bounds.size.height); CGPoint arcCenter = CGPointMake(0.5 * self.view.bounds.size.width, 0.5 * self.view.bounds.size.height); CGFloat arcRadius = 0.3 * MIN(self.view.bounds.size.width, self.view.bounds.size.height); CGMutablePathRef arcPath = CGPathCreateMutable(); CGPathMoveToPoint(arcPath, NULL, arcStart.x, arcStart.y); CGPathAddArc(arcPath, NULL, arcCenter.x, arcCenter.y, arcRadius, M_PI, 0, NO); // The layer we're going to animate (a 50x50pt red box) UIView* dynamicView = [[UIView alloc] initWithFrame: CGRectMake(0, 0, 50, 50)]; dynamicView.layer.backgroundColor = [[UIColor redColor] CGColor]; [self.view addSubview: dynamicView]; dynamicView.center = arcStart; // An additional view that shows the arc. BOOL showArc = NO; UIView* drawArcView = nil; if (showArc) { drawArcView = [[UIView alloc] initWithFrame: self.view.bounds]; CAShapeLayer* showArcLayer = [[CAShapeLayer alloc] init]; showArcLayer.frame = drawArcView.layer.bounds; showArcLayer.path = arcPath; showArcLayer.strokeColor = [[UIColor blackColor] CGColor]; showArcLayer.fillColor = nil; showArcLayer.lineWidth = 3.0; [drawArcView.layer addSublayer: showArcLayer]; [self.view insertSubview: drawArcView belowSubview: dynamicView]; } // The animation CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; pathAnimation.calculationMode = kCAAnimationPaced; pathAnimation.duration = 5.0; pathAnimation.path = arcPath; CGPathRelease(arcPath); // Add the animation and reset the state so we can run again. [CATransaction begin]; [CATransaction setCompletionBlock:^{ [drawArcView removeFromSuperview]; [dynamicView removeFromSuperview]; }]; [dynamicView.layer addAnimation:pathAnimation forKey:@"arc"]; [CATransaction commit]; } 

最终我用CGPathAddRelativeArc来获得我想要的转换。

 CGPoint viewCenter = dynamicView.objectCenter; CGMutablePathRef arcPath = CGPathCreateMutable(); CGPathMoveToPoint(arcPath, NULL, viewCenter.x, viewCenter.y); float angleOfRotation = self.angleIncrement; if (clockwise == NO) { angleOfRotation *= -1.0f; } float fullwayAngle = dynamicView.angle + angleOfRotation; CGPoint fullwayPoint = pointOnCircle(self.center, self.radius, fullwayAngle); CGPathAddRelativeArc(arcPath, NULL, self.center.x, self.center.y, self.radius, dynamicView.angle, angleOfRotation); pathAnimation.path = arcPath; CGPathRelease(arcPath); [dynamicView.layer addAnimation:pathAnimation forKey:@"arc"]; dynamicView.angle = fullwayAngle; dynamicView.objectCenter = fullwayPoint;