Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7404503
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 29, 20262026-05-29T05:15:54+00:00 2026-05-29T05:15:54+00:00

I am trying to create a simple and animated pie chart using CAShapeLayer .

  • 0

I am trying to create a simple and animated pie chart using CAShapeLayer. I want it to animate from 0 to a provided percentage.

To create the shape layer I use:

CGMutablePathRef piePath = CGPathCreateMutable();
CGPathMoveToPoint(piePath, NULL, self.frame.size.width/2, self.frame.size.height/2);
CGPathAddLineToPoint(piePath, NULL, self.frame.size.width/2, 0);
CGPathAddArc(piePath, NULL, self.frame.size.width/2, self.frame.size.height/2, radius, DEGREES_TO_RADIANS(-90), DEGREES_TO_RADIANS(-90), 0);        
CGPathAddLineToPoint(piePath, NULL, self.frame.size.width/2 + radius * cos(DEGREES_TO_RADIANS(-90)), self.frame.size.height/2 + radius * sin(DEGREES_TO_RADIANS(-90)));

pie = [CAShapeLayer layer];
pie.fillColor = [UIColor redColor].CGColor;
pie.path = piePath;

[self.layer addSublayer:pie];

Then to animate I use:

CGMutablePathRef newPiePath = CGPathCreateMutable();
CGPathAddLineToPoint(newPiePath, NULL, self.frame.size.width/2, 0);    
CGPathMoveToPoint(newPiePath, NULL, self.frame.size.width/2, self.frame.size.height/2);
CGPathAddArc(newPiePath, NULL, self.frame.size.width/2, self.frame.size.height/2, radius, DEGREES_TO_RADIANS(-90), DEGREES_TO_RADIANS(125), 0);                
CGPathAddLineToPoint(newPiePath, NULL, self.frame.size.width/2 + radius * cos(DEGREES_TO_RADIANS(125)), self.frame.size.height/2 + radius * sin(DEGREES_TO_RADIANS(125)));    

CABasicAnimation *pieAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
pieAnimation.duration = 1.0;
pieAnimation.removedOnCompletion = NO;
pieAnimation.fillMode = kCAFillModeForwards;
pieAnimation.fromValue = pie.path;
pieAnimation.toValue = newPiePath;

[pie addAnimation:pieAnimation forKey:@"animatePath"];

Obviously, this is animating in a really odd way. The shape just kind of grows into its final state. Is there an easy way to make this animation follow the direction of the circle? Or is that a limitation of CAShapeLayer animations?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-29T05:15:54+00:00Added an answer on May 29, 2026 at 5:15 am

    I know this question has long been answered, but I don’t quite think this is a good case for CAShapeLayer and CAKeyframeAnimation. Core Animation has the power to do animation tweening for us. Here’s a class (with a wrapping UIView, if you like) that I use to accomplish the effect pretty well.

    The layer subclass enables implicit animation for the progress property, but the view class wraps its setter in a UIView animation method. The interesting (and ultimately useful) side effect of using a 0.0 length animation with UIViewAnimationOptionBeginFromCurrentState is that each animation cancels out the previous one, leading to a smooth, fast, high-framerate pie, like this (animated) and this (not animated, but incremented).

    DZRoundProgressView.h

    @interface DZRoundProgressLayer : CALayer
    
    @property (nonatomic) CGFloat progress;
    
    @end
    
    @interface DZRoundProgressView : UIView
    
    @property (nonatomic) CGFloat progress;
    
    @end
    

    DZRoundProgressView.m

    #import "DZRoundProgressView.h"
    #import <QuartzCore/QuartzCore.h>
    
    @implementation DZRoundProgressLayer
    
    // Using Core Animation's generated properties allows
    // it to do tweening for us.
    @dynamic progress;
    
    // This is the core of what does animation for us. It
    // tells CoreAnimation that it needs to redisplay on
    // each new value of progress, including tweened ones.
    + (BOOL)needsDisplayForKey:(NSString *)key {
        return [key isEqualToString:@"progress"] || [super needsDisplayForKey:key];
    }
    
    // This is the other crucial half to tweening.
    // The animation we return is compatible with that
    // used by UIView, but it also enables implicit
    // filling-up-the-pie animations.
    - (id)actionForKey:(NSString *) aKey {
        if ([aKey isEqualToString:@"progress"]) {
            CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:aKey];
            animation.fromValue = [self.presentationLayer valueForKey:aKey];
            return animation;
        }
        return [super actionForKey:aKey];
    }
    
    // This is the gold; the drawing of the pie itself.
    // In this code, it draws in a "HUD"-y style, using
    // the same color to fill as the border.
    - (void)drawInContext:(CGContextRef)context {
        CGRect circleRect = CGRectInset(self.bounds, 1, 1);
    
        CGColorRef borderColor = [[UIColor whiteColor] CGColor];
        CGColorRef backgroundColor = [[UIColor colorWithWhite: 1.0 alpha: 0.15] CGColor];
    
        CGContextSetFillColorWithColor(context, backgroundColor);
        CGContextSetStrokeColorWithColor(context, borderColor);
        CGContextSetLineWidth(context, 2.0f);
    
        CGContextFillEllipseInRect(context, circleRect);
        CGContextStrokeEllipseInRect(context, circleRect);
    
        CGFloat radius = MIN(CGRectGetMidX(circleRect), CGRectGetMidY(circleRect));
        CGPoint center = CGPointMake(radius, CGRectGetMidY(circleRect));
        CGFloat startAngle = -M_PI / 2;
        CGFloat endAngle = self.progress * 2 * M_PI + startAngle;
        CGContextSetFillColorWithColor(context, borderColor);
        CGContextMoveToPoint(context, center.x, center.y);
        CGContextAddArc(context, center.x, center.y, radius, startAngle, endAngle, 0);
        CGContextClosePath(context);
        CGContextFillPath(context);
    
        [super drawInContext:context];
    }
    
    @end
    
    @implementation DZRoundProgressView
    + (Class)layerClass {
        return [DZRoundProgressLayer class];
    }
    
    - (id)init {
        return [self initWithFrame:CGRectMake(0.0f, 0.0f, 37.0f, 37.0f)];
    }
    
    - (id)initWithFrame:(CGRect)frame {
        if ((self = [super initWithFrame:frame])) {
            self.opaque = NO;
            self.layer.contentsScale = [[UIScreen mainScreen] scale];
            [self.layer setNeedsDisplay];
        }
        return self;
    }
    
    - (void)setProgress:(CGFloat)progress {
        [(id)self.layer setProgress:progress];
    }
    
    - (CGFloat)progress {
        return [(id)self.layer progress];
    }
    
    @end
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

HI im trying to create simple pie chart using the MS Chart controls. When
Im trying to create a simple pan and zoom app using silverlight 4, but
I am trying to create a simple dialog in MFC using Visual C++. My
I'm trying to create a simple toggling sidebar using jquery, where it expands and
I am trying to create a simple mouseover effect using a combination of mouseover,
I'm trying to create a simple database table using the PHP MySQL query Create
I'm trying to create a simple connection using the jdbc-odbc bridge: public static Connection
I'm trying to create a simple web project using Tomcat in Java. In the
I'm trying to create a simple note block application. I'm using AQGridView to display
trying to create a simple slider for an input. Using a survey gem that

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.