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.