I am trying to animate UIBezierPath
(from one path to another) in my custom UIView
when user touches my view (touchesEnded).
My drawing code:
- (void)drawRect:(CGRect)rect {
// Drawing code
[self createStartPath];
[self createEndPath];
CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGContextAddPath(currentContext, _startPath.CGPath);
CGContextDrawPath(currentContext, kCGPathStroke);
}
- (void) createStartPath
{
_startPath = UIBezierPath.bezierPath;
[_startPath moveToPoint: CGPointMake(18, 22.5)];
[_startPath addCurveToPoint: CGPointMake(18.38, 22.32) controlPoint1: CGPointMake(18.14, 22.5) controlPoint2: CGPointMake(18.29, 22.44)];
[_startPath addCurveToPoint: CGPointMake(18.32, 21.62) controlPoint1: CGPointMake(18.56, 22.11) controlPoint2: CGPointMake(18.53, 21.79)];
[_startPath addLineToPoint: CGPointMake(6.78, 12)];
[_startPath addLineToPoint: CGPointMake(18.32, 2.38)];
[_startPath addCurveToPoint: CGPointMake(18.38, 1.68) controlPoint1: CGPointMake(18.53, 2.21) controlPoint2: CGPointMake(18.56, 1.89)];
[_startPath addCurveToPoint: CGPointMake(17.68, 1.62) controlPoint1: CGPointMake(18.21, 1.47) controlPoint2: CGPointMake(17.89, 1.44)];
[_startPath addLineToPoint: CGPointMake(5.68, 11.62)];
[_startPath addCurveToPoint: CGPointMake(5.5, 12) controlPoint1: CGPointMake(5.56, 11.71) controlPoint2: CGPointMake(5.5, 11.85)];
[_startPath addCurveToPoint: CGPointMake(5.68, 12.38) controlPoint1: CGPointMake(5.5, 12.15) controlPoint2: CGPointMake(5.56, 12.29)];
[_startPath addLineToPoint: CGPointMake(17.68, 22.38)];
[_startPath addCurveToPoint: CGPointMake(18, 22.5) controlPoint1: CGPointMake(17.77, 22.46) controlPoint2: CGPointMake(17.89, 22.5)];
[_startPath closePath];
[self.fillColor setFill];
[_startPath fill];
}
- (void) createEndPath
{
_endPath = UIBezierPath.bezierPath;
[_endPath moveToPoint: CGPointMake(6, 22.5)];
[_endPath addCurveToPoint: CGPointMake(5.62, 22.32) controlPoint1: CGPointMake(5.86, 22.5) controlPoint2: CGPointMake(5.71, 22.44)];
[_endPath addCurveToPoint: CGPointMake(5.68, 21.62) controlPoint1: CGPointMake(5.44, 22.11) controlPoint2: CGPointMake(5.47, 21.79)];
[_endPath addLineToPoint: CGPointMake(17.22, 12)];
[_endPath addLineToPoint: CGPointMake(5.68, 2.38)];
[_endPath addCurveToPoint: CGPointMake(5.62, 1.68) controlPoint1: CGPointMake(5.47, 2.21) controlPoint2: CGPointMake(5.44, 1.89)];
[_endPath addCurveToPoint: CGPointMake(6.32, 1.62) controlPoint1: CGPointMake(5.79, 1.47) controlPoint2: CGPointMake(6.11, 1.44)];
[_endPath addLineToPoint: CGPointMake(18.32, 11.62)];
[_endPath addCurveToPoint: CGPointMake(18.5, 12) controlPoint1: CGPointMake(18.44, 11.71) controlPoint2: CGPointMake(18.5, 11.85)];
[_endPath addCurveToPoint: CGPointMake(18.32, 12.38) controlPoint1: CGPointMake(18.5, 12.15) controlPoint2: CGPointMake(18.44, 12.29)];
[_endPath addLineToPoint: CGPointMake(6.32, 22.38)];
[_endPath addCurveToPoint: CGPointMake(6, 22.5) controlPoint1: CGPointMake(6.23, 22.46) controlPoint2: CGPointMake(6.11, 22.5)];
[_endPath closePath];
[self.fillColor setFill];
//[_endPath fill];
}
I start my animation here (would like to "morph" one path to another):
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesEnded:touches withEvent:event];
CAShapeLayer * myLineShapeLayer = [[CAShapeLayer alloc] init];
CABasicAnimation * pathAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
pathAnimation.fromValue = (__bridge id)[_startPath CGPath];
pathAnimation.toValue = (__bridge id)[_endPath CGPath];
pathAnimation.duration = 3.0f;
[myLineShapeLayer addAnimation:pathAnimation forKey:@"animationKey"];
}
I see the startPath
and my touchesEnded
is called, but nothing animates neither endPath
is shown.
For your animation to work, please add your myLineShapeLayer
as a sublayer of your view's layer
:
For instance, in viewDidLoad
:
[self.view.layer addSublayer:myLineShapeLayer];
In order to be able to see the endPath
still being persistently seen on the screen after the animation, we could first assign the endPath
to the path
property of the CAShapeLayer
:
myLineShapeLayer.path = [endPath CGPath];
And thusly we animate without toValue
:
CABasicAnimation * pathAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
pathAnimation.fromValue = (__bridge id)[_startPath CGPath];
pathAnimation.duration = 3.0f;
[myLineShapeLayer addAnimation:pathAnimation forKey:@"animationKey"];
The end effect of the animation would then remain on the screen after the animation.
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.