在自定义 UIView 中动画化 UIBezierPath 不起作用
Animating UIBezierPath in custom UIView doesn't work
当用户触摸我的视图 (touchesEnded) 时,我正在尝试在我的自定义 UIView
中设置动画 UIBezierPath
(从一条路径到另一条路径)。
我的绘图代码:
- (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];
}
我从这里开始制作动画(想将一条路径“变形”为另一条路径):
- (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"];
}
我看到了 startPath
并且调用了我的 touchesEnded
,但是没有任何动画,也没有显示 endPath
。
为了使您的动画正常工作,请将您的 myLineShapeLayer
添加为视图 layer
的子层:
例如,在viewDidLoad
中:
[self.view.layer addSublayer:myLineShapeLayer];
为了能够看到endPath
在动画结束后仍然持续出现在屏幕上,我们可以先将endPath
分配给path
属性 的 CAShapeLayer
:
myLineShapeLayer.path = [endPath CGPath];
因此我们在没有 toValue
的情况下制作动画:
CABasicAnimation * pathAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
pathAnimation.fromValue = (__bridge id)[_startPath CGPath];
pathAnimation.duration = 3.0f;
[myLineShapeLayer addAnimation:pathAnimation forKey:@"animationKey"];
动画的结束效果将在动画结束后保留在屏幕上。
当用户触摸我的视图 (touchesEnded) 时,我正在尝试在我的自定义 UIView
中设置动画 UIBezierPath
(从一条路径到另一条路径)。
我的绘图代码:
- (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];
}
我从这里开始制作动画(想将一条路径“变形”为另一条路径):
- (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"];
}
我看到了 startPath
并且调用了我的 touchesEnded
,但是没有任何动画,也没有显示 endPath
。
为了使您的动画正常工作,请将您的 myLineShapeLayer
添加为视图 layer
的子层:
例如,在viewDidLoad
中:
[self.view.layer addSublayer:myLineShapeLayer];
为了能够看到endPath
在动画结束后仍然持续出现在屏幕上,我们可以先将endPath
分配给path
属性 的 CAShapeLayer
:
myLineShapeLayer.path = [endPath CGPath];
因此我们在没有 toValue
的情况下制作动画:
CABasicAnimation * pathAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
pathAnimation.fromValue = (__bridge id)[_startPath CGPath];
pathAnimation.duration = 3.0f;
[myLineShapeLayer addAnimation:pathAnimation forKey:@"animationKey"];
动画的结束效果将在动画结束后保留在屏幕上。