可以在两个方向上制作动画的动画饼图

时间:2014-07-07 05:28:52

标签: ios7 uiview core-animation calayer blending

我正在尝试构建一个动画饼图,可以根据其progress的值是增加还是减少,在两个方向上设置饼图动画。我已开始提供here提供的示例代码,并根据建议进行了一些调整here

麻烦的是背景动画还没有完全奏效。它只是部分清除馅饼。我不太确定这是因为我错误地使用动画还是错误地计算坐标,因为如果我将CGContextSetFillColorWithColor(context, UIColor.redColor.CGColor);插入第一个if分支并将混合模式更改为kCGBlendModeNormal,那么结果同样关闭。

所以这是我目前的代码(摘自PieLayer.m) - 谁能提出改进建议?

- (void)drawInContext:(CGContextRef)context {
    PieView *pieView = self.delegate;
    NSAssert(pieView != nil, nil);

    CGRect rect = CGRectInset(self.bounds, 1, 1);

    CGFloat radius = MIN(CGRectGetMidX(rect), CGRectGetMidY(rect));
    CGPoint center = CGPointMake(radius, CGRectGetMidY(rect));

    CGContextSetFillColorWithColor(context, UIColor.clearColor.CGColor);
    CGContextSetStrokeColorWithColor(context, pieView.circumferenceTintColor.CGColor);
    CGContextSetLineWidth(context, 2.0f);

    CGContextFillEllipseInRect(context, rect);
    CGContextStrokeEllipseInRect(context, rect);

    CGFloat startAngle   = -M_PI / 2;
    CGFloat endAngle     = self.progress     * 2 * M_PI + startAngle;
    CGFloat lastEndAngle = self.lastProgress * 2 * M_PI + startAngle;

    if (self.lastProgress > self.progress) {
        NSLog(@"clear sector between progress=%f and lastProgress=%f", self.progress, self.lastProgress);

        CGContextMoveToPoint(context, center.x, center.y);
        CGContextAddArc(context, center.x, center.y, radius, endAngle, lastEndAngle, 0);
        CGContextClosePath(context);

        CGContextSetBlendMode(context, kCGBlendModeClear);
        CGContextFillPath(context);
    }

    if (self.progress > 0) {
        NSLog(@"draw sector to progress=%f (lastProgress=%f)", self.progress, self.lastProgress);

        CGContextSetFillColorWithColor(context, pieView.sectorTintColor.CGColor);

        CGContextMoveToPoint(context, center.x, center.y);
        CGContextAddArc(context, center.x, center.y, radius, startAngle, endAngle, 0);
        CGContextClosePath(context);

        CGContextSetBlendMode(context, kCGBlendModeNormal);
        CGContextFillPath(context);
    }

    ((PieLayer *)self.modelLayer).lastProgress = self.progress;

    [super drawInContext:context];
}

1 个答案:

答案 0 :(得分:1)

您发布的答案中的代码(animated CAShapeLayer pie)在我看来都很方便,即使使用clearColor:请参阅this video
clearColor不能产生正确行为的唯一情况是背景颜色是实心并且前景是清晰的:在这种情况下,需要更改混合模式,正如您在代码中指出的那样。 / p>

我尝试了这三种配置,在所有情况下,图层都正确地响应-setProgress:

  • DZRoundProgressView作为主要UIView;
  • 的子视图
  • 主视图类设置为DZRoundProgressView;
  • DZRoundProgressView作为主UIView;
  • 的子图层

此外,前一帧中的图层内容不太可能在下一次绘制调用时仍然可见:显然,-drawInContext:的默认行为是在执行前清除上下文,如{{3说 如果您没有使用图层的contents属性,并且您没有破解绘图管道,那么self.progress的值可能会出错;也许是表示层和模型层的一些问题,或者在属性的实现中。

事实上,这并不能解决您的问题,因为我无法复制或隔离它,但应该允许您解决它。