廢話不多說,先看上效果,由於動畫錄製的時候幀率限制,只能將動畫放慢了進行錄製,更容易看到效果 這是點擊開始之後代碼 由於動畫使由多個動畫組成,所以第一個動畫完畢之後自動再次開始一個動畫 先解釋一下動畫執行過程 第一步是通過CABasicAnimation 對照片進行縮放 第二步是通過CAKeyfra ...
廢話不多說,先看上效果,由於動畫錄製的時候幀率限制,只能將動畫放慢了進行錄製,更容易看到效果
這是點擊開始之後代碼
-(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 就是這個函數的兩個輸入的控制點參數