CAKeyframeAnimation跟CABasicAnimation的区别是:CABasicAnimation只能从一个Value变到另一个Value,而CAKeyframeAnimation会将这些数值保存在数组中或者以路径(path)形式保存.
另附代码如下:
- (instancetype)initWithFrame:(CGRect)frame withSuperView:(UIView *)superView{ if (self = [super initWithFrame:frame]) { self.superView = superView; self.borderColor = [UIColor whiteColor]; self.fillColor = [UIColor colorWithRed:(arc4random_uniform(255))/255.0 green:(arc4random_uniform(255))/255.0 blue:(arc4random_uniform(255))/255.0 alpha:1]; self.backgroundColor = [UIColor clearColor]; self.layer.anchorPoint = CGPointMake(0.5, 1); } return self;}- (void)addAnimationView{ // 初始化 self.transform = CGAffineTransformMakeScale(0, 0); self.alpha = 0; [UIView animateWithDuration:0.5 delay:0.0 usingSPRingWithDamping:0.6 initialSpringVelocity:0.8 options:UIViewAnimationOptionCurveEaSEOut animations:^{ self.transform = CGAffineTransformIdentity; self.alpha = 0.9; } completion:^(BOOL finished) { }]; // 随机数 NSInteger i = arc4random_uniform(2); NSInteger rotationDirection = 1 - (2*i); // 绘制路径 UIBezierPath *heartTravelPath = [UIBezierPath bezierPath]; [heartTravelPath moveToPoint:self.center]; CGPoint endPoint = CGPointMake(self.centerX + (rotationDirection) * arc4random_uniform(2*self.width), self.superView.height/6.0 + arc4random_uniform(self.superView.height/4.0)); CGFloat x = (self.width/2.0 + arc4random_uniform(2*self.width)) * rotationDirection; CGFloat y = MAX(endPoint.y ,MAX(arc4random_uniform(8*self.width), self.width)); CGPoint controlPoint1 = CGPointMake(self.centerX + x, self.superView.height - y); CGPoint controlPoint2 = CGPointMake(self.centerX - 2*x, y); [heartTravelPath addCurveToPoint:endPoint controlPoint1:controlPoint1 controlPoint2:controlPoint2]; CAKeyframeAnimation *keyFrameAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; keyFrameAnimation.path = heartTravelPath.CGPath; keyFrameAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; keyFrameAnimation.duration = liveAnimationDuration + endPoint.y/self.superView.height; [self.layer addAnimation:keyFrameAnimation forKey:@"positionOnPath"]; [UIView animateWithDuration:liveAnimationDuration animations:^{ self.alpha = 0.0; } completion:^(BOOL finished) { [self removeFromSuperview]; }];}- (void)drawRect:(CGRect)rect{ [self.fillColor setFill]; [self.borderColor setStroke]; CGFloat drawingPadding = 2.0; CGFloat curveRadius = floor((CGRectGetWidth(rect) - 2*drawingPadding) / 4.0); UIBezierPath *heartPath = [UIBezierPath bezierPath]; CGPoint tipLocation = CGPointMake(floor(CGRectGetWidth(rect) / 2.0), CGRectGetHeight(rect) - drawingPadding); [heartPath moveToPoint:tipLocation]; CGPoint topLeftCurveStart = CGPointMake(drawingPadding, floor(CGRectGetHeight(rect) / 3)); [heartPath addQuadCurveToPoint:topLeftCurveStart controlPoint:CGPointMake(topLeftCurveStart.x, topLeftCurveStart.y + curveRadius)]; [heartPath addArcWithCenter:CGPointMake(topLeftCurveStart.x + curveRadius, topLeftCurveStart.y) radius:curveRadius startAngle:M_PI endAngle:0 clockwise:YES]; CGPoint topRightCurveStart = CGPointMake(topLeftCurveStart.x + 2*curveRadius, topLeftCurveStart.y); [heartPath addArcWithCenter:CGPointMake(topRightCurveStart.x + curveRadius, topRightCurveStart.y) radius:curveRadius startAngle:M_PI endAngle:0 clockwise:YES]; CGPoint topRightCurveEnd = CGPointMake(topLeftCurveStart.x + 4*curveRadius, topRightCurveStart.y); [heartPath addQuadCurveToPoint:tipLocation controlPoint:CGPointMake(topRightCurveEnd.x, topRightCurveEnd.y + curveRadius)]; [heartPath fill]; heartPath.lineWidth = 1; heartPath.lineCapStyle = kCGLineCapRound; heartPath.lineJoinStyle = kCGLineCapRound; [heartPath stroke];}注:
values:动画移动的点
path:动画移动路径。path只对CALayer的anchorPoint和position起作用。path比values优先级高,所以如果path有值,那么values将被忽略.
keyTimes:为对应的关键帧设置对应的时间点(取值范围为0到1.0),keyTimes中的每一个时间值都对应values中的每一帧.默认各个关键帧的时间是平分的.
新闻热点
疑难解答