iOS中的动画饼图

Axe*_*eva 5 animation objective-c calayer ios pie-chart

我正在尝试在iOS中创建一个动画饼图,其行为基本上如下:

饼图进展

简而言之,它以灰色圆圈开始,随着动画的进行,箭头围绕圆圈移动,直到达到我指定的百分比.

我已经使用了Zachary Waldowski在这个SO问题中发布的示例代码:

动画CAShapeLayer Pie

这让我到了可以创建基本动画的地步.栗色馅饼的长度达到了正确的大小.我正在努力的是如何将箭头映射到动画,以便随着饼图的增长而拖动它.

有关如何实现这一目标的任何想法?

Axe*_*eva 4

好的,我已经找到解决方案了。

在Zachary Waldowski创建的作品的基础上(请参阅我原来的帖子),我能够在CALayer.

简而言之,我用栗色画一个外圆,用浅灰色画一个较小的圆,用白色画一条描边路径,然后手工画出箭头尖端的三角形。

这是发挥神奇作用的相关代码部分:

- (void)drawInContext:(CGContextRef)context {
    CGRect circleRect = CGRectInset(self.bounds, 1, 1);
    CGFloat startAngle = -M_PI / 2;
    CGFloat endAngle = self.progress * 2 * M_PI + startAngle;

    CGColorRef outerPieColor = [[UIColor colorWithRed: 137.0 / 255.0 green: 12.0 / 255.0 blue: 88.0 / 255.0 alpha: 1.0] CGColor];
    CGColorRef innerPieColor = [[UIColor colorWithRed: 235.0 / 255.0 green: 214.0 / 255.0 blue: 227.0 / 255.0 alpha: 1.0] CGColor];
    CGColorRef arrowColor = [[UIColor whiteColor] CGColor];

    // Draw outer pie
    CGFloat outerRadius = CGRectGetMidX(circleRect);
    CGPoint center = CGPointMake(CGRectGetMidX(circleRect), CGRectGetMidY(circleRect));

    CGContextSetFillColorWithColor(context, outerPieColor);
    CGContextMoveToPoint(context, center.x, center.y);
    CGContextAddArc(context, center.x, center.y, outerRadius, startAngle, endAngle, 0);
    CGContextClosePath(context);
    CGContextFillPath(context);

    // Draw inner pie
    CGFloat innerRadius = CGRectGetMidX(circleRect) * 0.45;

    CGContextSetFillColorWithColor(context, innerPieColor);
    CGContextMoveToPoint(context, center.x, center.y);
    CGContextAddArc(context, center.x, center.y, innerRadius, startAngle, endAngle, 0);
    CGContextClosePath(context);
    CGContextFillPath(context);

    // Draw the White Line
    CGFloat lineRadius = CGRectGetMidX(circleRect) * 0.72;
    CGFloat arrowWidth = 0.35;

    CGContextSetStrokeColorWithColor(context, arrowColor);
    CGContextSetFillColorWithColor(context, arrowColor);

    CGMutablePathRef path = CGPathCreateMutable();
    CGContextSetLineWidth(context, 16);
    CGFloat lineEndAngle = ((endAngle - startAngle) >= arrowWidth) ? endAngle - arrowWidth : endAngle;
    CGPathAddArc(path, NULL, center.x, center.y, lineRadius, startAngle, lineEndAngle, 0);
    CGContextAddPath(context, path);
    CGContextStrokePath(context);

    // Draw the Triangle pointer
    CGFloat arrowStartAngle = lineEndAngle - 0.01;
    CGFloat arrowOuterRadius = CGRectGetMidX(circleRect) * 0.90;
    CGFloat arrowInnerRadius = CGRectGetMidX(circleRect) * 0.54;

    CGFloat arrowX = center.x + (arrowOuterRadius * cosf(arrowStartAngle));
    CGFloat arrowY = center.y + (arrowOuterRadius * sinf(arrowStartAngle));

    CGContextMoveToPoint   (context, arrowX, arrowY);  // top corner

    arrowX = center.x + (arrowInnerRadius * cosf(arrowStartAngle));
    arrowY = center.y + (arrowInnerRadius * sinf(arrowStartAngle));

    CGContextAddLineToPoint(context, arrowX, arrowY);  // bottom corner

    arrowX = center.x + (lineRadius * cosf(endAngle));
    arrowY = center.y + (lineRadius * sinf(endAngle));

    CGContextAddLineToPoint(context, arrowX, arrowY);  // point
    CGContextClosePath(context);
    CGContextFillPath(context);

    [super drawInContext: context];
}
Run Code Online (Sandbox Code Playgroud)