iOS中的动画饼图

时间:2014-01-06 14:50:22

标签: ios objective-c animation calayer pie-chart

我正在尝试在iOS中创建一个基本上像这样的动画饼图:

Pie chart progression

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

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

Animated CAShapeLayer Pie

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

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

2 个答案:

答案 0 :(得分: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];
}

答案 1 :(得分:2)

将带有箭头的饼图作为图像。

在每个步骤中,绘制此图像,稍微旋转一下。在图像上绘制灰色饼图,为图像旋转选择正确的角度。