I'm trying to animation the transition of a CALayer from normal corners to rounded corners. I only want to round the top corners, so I am using a UIBezierPath. Here's the code:
UIRectCorner corners = UIRectCornerTopLeft | UIRectCornerTopRight;
UIBezierPath* newPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(8.0f, 8.0f)];
UIBezierPath* oldPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(0.0f, 0.0f)];
CAShapeLayer* layer = [CAShapeLayer layer];
layer.frame = self.bounds;
layer.path = oldPath.CGPath;
self.layer.mask = layer;
CABasicAnimation* a = [CABasicAnimation animationWithKeyPath:@"path"];
[a setDuration:0.4f];
[a setFromValue:(id)layer.path];
[a setToValue:(id)newPath.CGPath];
layer.path = newPath.CGPath;
[layer addAnimation:a forKey:@"path"];
But when I run this, the corners are rounded, but there is no animation- it happens instantly. I have seen some similar questions here on SO, but they didn't solve my problem.
iPhone CALayer animation
Animating CALayer's shadowPath property
I'm sure that I'm just doing one little thing wrong which is causing the problem, but for the life of me I can't figure it out.
Solution:
- (void)roundCornersAnimated:(BOOL)animated {
UIRectCorner corners = UIRectCornerTopLeft | UIRectCornerTopRight;
UIBezierPath* newPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(8.0f, 8.0f)];
UIBezierPath* oldPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(0.0001f, 0.0001f)];
CAShapeLayer* layer = [CAShapeLayer layer];
layer.frame = self.bounds;
self.layer.mask = layer;
if(animated) {
CABasicAnimation* a = [CABasicAnimation animationWithKeyPath:@"path"];
[a setDuration:0.4f];
[a setFromValue:(id)oldPath.CGPath];
[a setToValue:(id)newPath.CGPath];
layer.path = newPath.CGPath;
[layer addAnimation:a forKey:@"path"];
} else {
layer.path = newPath.CGPath;
}
}
Really all I needed to do was set a proper 'from' value for the animation.