iPhone Core Animation – Drawing a Circle

I wish to create an animation. The best way I can explain this is if you can imagine drawing a circle. It starts at the top or 12 o clock and draws clockwise all the way around until it becomes a complete circle over the space of 10 or so seconds.

The closet I have come to this is to draw a point rotating around a center point using Core Animation (using the sample code here). But I am at a loss on how to draw the circle? Any suggestions are very welcome.

Many Thanks 🙂

html canvas – drawing circle with animation & number

i’m totally new in javascript and css3. What I would like to achieve is to have an animation of drawing circle (in fact four of them). Everything should work like that: 1. animation of circle #1 and a

Core Animation problem on iPhone

I’m new to iPhone development, and doing some experimentation with Core Animation. I’ve run into a small problem regarding the duration of the animation I’m attempting. Basically, Ive got a view with

Core Animation performance on iphone

I’m trying to do some animations using Core Animation on the iphone. I’m using CABasicAnimation on CALayer. It’s a straight forward animation from a random place at the top of the screen to the bottom

Arc / Circle animation in iphone

How would I animate a circle on the iPhone so that the arc starts at 0 degrees and ends at 360 degrees? Advance Thanks, Sat

Core Animation with a Core Graphics drawing

I am inside a UIView subclass (CustomView in the code below). I am drawing a border around an image in a UIImageView subclass (containerView). The Core Graphics code for this is located inside drawInR

iPhone: Drawing a curved line until it becomes a circle animation

I wish to draw a curved line until it makes a full rotation and joins to become a complete circle, just the circle outline, not filled. This has to be animated over a number of seconds. Can anyone poi

Loading circle animation in iphone

How can I display the loading screen animation in iphone? I mean the bars arranged in circles. So that I can use it while some of the part of my app is loading, like initializing. Or should I create m

Help drawing circle in iPhone

The following is a snippet of code where I am trying to draw a circle but my x value prints as a constant value. It’s most likely something very very simple. Thanks in advance for any help. int sides

Core-Plot iPhone Animation Examples

I’ve been looking into core-plot for the iPhone and I’m having trouble finding any examples of animation actually being used. What I need to see is an example of how to use core-plots animation to add

Core Animation for Games FPS (iPhone)

I recently started learning OpenGL ES for iPhone Development, but several people on Stack Overflow mentioned that Core Animation with images is a lot easier than OpenGL (for 2D games). I read up on CA

Answers

Ok I have a partial fix. I found the following code that draws segments of a circle. Its basically a UIView subclass that gets its drawRect fired every time its progress should be updated. The only question I have now is how would I change it so that instead of drawing sections or slices it would just draw the circle stroke?

-(void)drawRect:(CGRect)rect 
{
    // Drawing code

    CGRect allRect = self.bounds;
    CGRect circleRect = CGRectInset(allRect, 2.0f, 2.0f);

    CGContextRef context = UIGraphicsGetCurrentContext();

    // Draw background
    CGContextSetRGBStrokeColor(context, self.strokeValueRed, self.strokeValueGreen, self.strokeValueBlue, self.strokeValueAlpha); // white
    CGContextSetRGBFillColor(context, 1.0f, 1.0f, 1.0f, 0.1f); // translucent white
    CGContextSetLineWidth(context, self.lineWidth);
    CGContextFillEllipseInRect(context, circleRect);
    CGContextStrokeEllipseInRect(context, circleRect);

    // Draw progress
    CGPoint center = CGPointMake(allRect.size.width / 2, allRect.size.height / 2);
    CGFloat radius = (allRect.size.width - 4) / 2;
    CGFloat startAngle = - ((float)M_PI / 2); // 90 degrees
    CGFloat endAngle = (self.progress * 2 * (float)M_PI) + startAngle;
    CGContextSetRGBFillColor(context, 1.0f, 1.0f, 1.0f, 1.0f); // white
    CGContextMoveToPoint(context, center.x, center.y);
    CGContextAddArc(context, center.x, center.y, radius, startAngle, endAngle, 0);
    CGContextClosePath(context);
    CGContextFillPath(context);
}

I got a solution to this problem, code below. I seem to have messed up in my explanation of the problem at hand so rewrote it as another question that got answered with the correct solution, see here

thanks everyone for their advice!

-(void)drawRect:(CGRect)rect
{
    // Drawing code

    CGRect allRect = self.bounds;
    CGContextRef context = UIGraphicsGetCurrentContext();

    // Draw background
    CGContextSetRGBStrokeColor(context, self.strokeValueRed, self.strokeValueGreen, self.strokeValueBlue, self.strokeValueAlpha); // white
    CGContextSetLineWidth(context, 5);

    // Draw progress
    CGPoint center = CGPointMake(allRect.size.width / 2, allRect.size.height / 2);
    CGFloat radius = (allRect.size.width - 4) / 2;
    CGFloat startAngle = - ((float)M_PI / 2); // 90 degrees
    CGFloat endAngle = (self.progress * 2 * (float)M_PI) + startAngle;
    CGContextAddArc(context, center.x, center.y, radius, startAngle, endAngle, 0);
    CGContextStrokePath(context);
}

What you really should do is to animate the stroke of a CAShapeLayer where the path is a circle. This will be accelerated using Core Animation and is less messy then to draw part of a circle in -drawRect:.

The code below will create a circle shape layer in the center of the screen and animate the stroke of it clockwise so that it looks as if it is being drawn. You can of course use any shape you’d like. (You can read this article on Ole Begemanns blog to learn more about how to animate the stroke of a shape layer.)

Note: that the stoke properties are not the same as the border properties on the layer. To change the width of the stroke you should use “lineWidth” instead of “borderWitdh” etc.

// Set up the shape of the circle
int radius = 100;
CAShapeLayer *circle = [CAShapeLayer layer];
// Make a circular shape
circle.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 2.0*radius, 2.0*radius) 
                                         cornerRadius:radius].CGPath;
// Center the shape in self.view
circle.position = CGPointMake(CGRectGetMidX(self.view.frame)-radius, 
                              CGRectGetMidY(self.view.frame)-radius);

// Configure the apperence of the circle
circle.fillColor = [UIColor clearColor].CGColor;
circle.strokeColor = [UIColor blackColor].CGColor;
circle.lineWidth = 5;

// Add to parent layer
[self.view.layer addSublayer:circle];

// Configure animation
CABasicAnimation *drawAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
drawAnimation.duration            = 10.0; // "animate over 10 seconds or so.."
drawAnimation.repeatCount         = 1.0;  // Animate only once..

// Animate from no part of the stroke being drawn to the entire stroke being drawn
drawAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
drawAnimation.toValue   = [NSNumber numberWithFloat:1.0f];

// Experiment with timing to get the appearence to look the way you want
drawAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];

// Add the animation to the circle
[circle addAnimation:drawAnimation forKey:@"drawCircleAnimation"];

Here is another solution to the problem, based off @David’s answer. This approach lets you set the direction of the circle’s animation, and offers slightly more control. Edit: I’ve written a blog post on how to draw a circle with Swift, which I’ll try to keep up to date with the betas. Check there if the code below doesn’t work for you.

let radius = 100.0

// Create the circle layer
var circle = CAShapeLayer()

// Set the center of the circle to be the center of the view
let center = CGPointMake(CGRectGetMidX(self.frame) - radius, CGRectGetMidY(self.frame) - radius)

let fractionOfCircle = 3.0 / 4.0

let twoPi = 2.0 * Double(M_PI)
// The starting angle is given by the fraction of the circle that the point is at, divided by 2 * Pi and less
// We subtract M_PI_2 to rotate the circle 90 degrees to make it more intuitive (i.e. like a clock face with zero at the top, 1/4 at RHS, 1/2 at bottom, etc.)
let startAngle = Double(fractionOfCircle) / Double(twoPi) - Double(M_PI_2)
let endAngle = 0.0 - Double(M_PI_2)
let clockwise: Bool = true

// `clockwise` tells the circle whether to animate in a clockwise or anti clockwise direction
circle.path = UIBezierPath(arcCenter: center, radius: radius, startAngle: CGFloat(startAngle), endAngle: CGFloat(endAngle), clockwise: clockwise).CGPath

// Configure the circle
circle.fillColor = UIColor.blackColor().CGColor
circle.strokeColor = UIColor.redColor().CGColor
circle.lineWidth = 5

// When it gets to the end of its animation, leave it at 0% stroke filled
circle.strokeEnd = 0.0

// Add the circle to the parent layer
self.layer.addSublayer(circle)

// Configure the animation
var drawAnimation = CABasicAnimation(keyPath: "strokeEnd")
drawAnimation.repeatCount = 1.0

// Animate from the full stroke being drawn to none of the stroke being drawn
drawAnimation.fromValue = NSNumber(double: fractionOfCircle)
drawAnimation.toValue = NSNumber(float: 0.0)

drawAnimation.duration = 30.0

drawAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)

// Add the animation to the circle
circle.addAnimation(drawAnimation, forKey: "drawCircleAnimation")