简体   繁体   中英

Animation - Drawing a circle in iOS - Not animating complete circle

I'm using the following code to draw part of a circle. I'm a bit confused, however, because at the end of the animation it seems to immediately fill in the rest of the circle. Why is this happening?

// Set up the shape of the circle
int radius = 62;
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(18, 92);

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

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

// Configure animation
CABasicAnimation *drawAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
drawAnimation.duration            = .8; // "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:0.4f];

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

This is happening because by default a CAAnimation is removed from the layer when it completes. This means that it will remove the value that you animated to and set it to the default of 1.0 right after the animation finished. Since you are using a CAAnimation the layer is never actually changing its properties it just only looks like it is which is why when the animation is removed it gets set to 1.0 because that is what the layer's value for strokeEnd is since you never changed it. Try to see this yourself by printing the value of strokeEnd while the animation is happening.

This can be solved in 2 ways, setting the final storkeEnd value before you start the animation so that when it is removed it is still 0.4 or by adding certain properties to your CABasicAnimation . The properties you need to set to achieve what you are looking for are:

drawAnimation.fillMode = kCAFillModeForwards

and

drawAnimation.removedOnCompletion = false

Hope that helps

For the whole stroke to be animated drawAnimation.fromValue should be 0.0 and drawAnimation.toValue should be 1.0 . These values determine what percentage of the stroke is animated.

drawAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
drawAnimation.toValue   = [NSNumber numberWithFloat:1.0f];

fromValue : Defines the value the receiver uses to start interpolation.
toValue : Defines the value the receiver uses to end interpolation.

What you used was 0.4 for drawAnimation.toValue . So it ends at 40% of the animation and draws the rest in one go without animating.

For example if you set drawAnimation.fromValue = 0.5 and drawAnimation.toValue = 1.0 , animation will start from half a circle. if you set drawAnimation.fromValue = 0.0 and drawAnimation.toValue = 0.5 , animation will end at half a circle and draw the rest without animation.

If you only wanted to draw 40% of the circle, you can use a different function to create the circle path.

CGFloat startAngle = (-M_PI/2);
CGFloat endAngle = startAngle + 0.4*(2*M_PI);

circle.path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(radius, radius)
                                                      radius:radius
                                                  startAngle:startAngle
                                                    endAngle:endAngle
                                                   clockwise:YES].CGPath;

The above code actually generates 40% of a circle path from startAngle = -M_PI/2 . You can vary the angle according to your needs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM