废话不多说,先看上效果,由于动画录制的时候帧率限制,只能将动画放慢了进行录制,更容易看到效果
这是点击开始之后代码
-(IBAction)btnStartClick:(id)sender { CABasicAnimation *baseanimation1=[CABasicAnimation animationWithKeyPath:@"transform.scale.x"]; baseanimation1.fromValue=@(1.0f); baseanimation1.toValue=@(20.0f/myview.frame.size.width); CABasicAnimation *baseanimation2=[CABasicAnimation animationWithKeyPath:@"transform.scale.y"]; baseanimation2.fromValue=@(1.0f); baseanimation2.toValue=@(20.0f/myview.frame.size.height); CAAnimationGroup *cg=[CAAnimationGroup animation]; cg.duration=0.2; cg.animations=@[baseanimation1,baseanimation2]; cg.repeatCount=0; cg.delegate=self; cg.removedOnCompletion=NO; [myview.layer addAnimation:cg forKey:@"myviewscale"]; }
由于动画使由多个动画组成,所以第一个动画完毕之后自动再次开始一个动画
-(void) animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { if(anim==[myview.layer animationForKey:@"myviewscale"]) { myview.frame=CGRectMake((self.view.frame.size.width-20)/2,(self.view.frame.size.height-20)/2, 20, 20); [myview.layer removeAnimationForKey:@"myviewscale"]; UIBezierPath *path=[UIBezierPath bezierPath]; [path moveToPoint:self.view.center]; [path addQuadCurveToPoint:CGPointMake(20, self.view.frame.size.height-20) controlPoint:CGPointMake(35, 50)]; CAKeyframeAnimation *keyframeanimation1=[CAKeyframeAnimation animationWithKeyPath:@"position"]; keyframeanimation1.path=path.CGPath; keyframeanimation1.duration=1; //keyframeanimation1.rotationMode = kCAAnimationRotateAuto; keyframeanimation1.rotationMode = nil; keyframeanimation1.delegate=self; keyframeanimation1.removedOnCompletion=NO; keyframeanimation1.fillMode = kCAFillModeForwards; keyframeanimation1.timingFunction=[CAMediaTimingFunction functionWithControlPoints:0.3 :0.7 :0.7 :0.3]; [myview.layer addAnimation:keyframeanimation1 forKey:@"myviewposition"]; } else { myview.frame=CGRectMake(10,self.view.frame.size.height-20, 20, 20); [myview.layer removeAnimationForKey:@"myviewposition"]; } }
先解释一下动画执行过程
第一步是通过CABasicAnimation 对照片进行缩放
第二步是通过CAKeyframeAnimation 对照片进行位移并最终产生抛物线的投掷效果
抛物线轨迹的实现
要想让动画有一个抛物线的轨迹就需要一个二次贝塞尔曲线的轨迹进行模拟,二次贝塞尔曲线如下,这里引用了一个网络的动画图片。
二次贝塞尔曲线中 p0 为起始点、p1 为控制点、 p2为结束点
UIBezierPath 的实例方法 addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint;要求输入一个结束点(p2) 和 控制点(p1),然后这个函数将为我们自动构建一个二次贝塞尔曲线。
抛物线速度控制
抛物线速度前半段由快变慢,后半段由慢变快是由CAKeyframeAnimation 的 timingFunction 进行控制的,timingFunction是CAMediaTimingFunction类型的。CAMediaTimingFunction可以通过functionWithName:(NSString *)name 进行初始化,输入值 name的取值范围包括 linear(数值平均增长)、easeIn(先快后慢)、easeOut(先慢后快)、easeInEaseOut(先快后慢先慢后快)。也可以通过 functionWithControlPoints:(float)c1x :(float)c1y :(float)c2x :(float)c2y 进行初始化,输入值为三次贝塞尔曲线的两个控制点坐标,控制点坐标取值范围都是在[0,1]之间。因此通过functionWithName函数是无法满足我们的需求的,那么只能使用函数functionWithControlPoints了。
functionWithControlPoints所使用的三次贝塞尔曲线大概可以使用下图进行表示(图片来源于网络,请忽略图片上面的横纵坐标文字):
横向坐标定义为需要变化的数值 ,纵坐标定义为时间 那么 p1 和 p2 就是这个函数的两个输入的控制点参数