沒看他代碼之前,我想了半天應該怎么實現這個效果:
這個藍色的view拉了之后是個不規則的形狀,雖然只有一邊是不規則的,但是也不能直接用frame動畫來做了,
那就只能用CAShapeLayer來自己畫形狀了,要畫一個這樣的形狀,還不能直接用 UIBezierPath已經提供的方便的類方法來畫,
只能用 Path construction的方法來畫;但是如果用Path construction的方法來畫的話,動畫做起來就麻煩了,
因為path的動畫不太好控制,只寫好path的初始值和最終值,不知道系統會怎么樣給動畫插值;
在這里因為只有一個邊在動,所以還能控制,那剩下的問題就是怎么讓動畫跟著手勢變動。
這個就只能寫個以位移為參數的生成當時整個形狀的貝塞爾曲線的函數。。。。
然后以手勢移動量來設置path就行了。
問題是解決了,但是實現起來好麻煩。。。所以這個方案也就僅停留在理論階段了。
然后看了作者代碼,發現他的實現比我想的簡單的多:
在這個藍色的view上覆蓋一個CAShaperLayer,將其填充色設置為其他顏色,然后只需要寫在動的一邊的貝塞爾曲線就行了!
這樣的效果看起來就像是你在拖動一個矩形的某一邊,但實際上你只是拖動了在屏幕外的一條線,拖出來一個新的layer覆蓋住了原來的view。
讓我發現了一個看似簡單但很容易忽略的事實:
眼睛看到的動畫效果可以用 跟它看上去不一樣的方式甚至完全相反的方式來實現,而且實現起來說不定更簡單~~
就比如說上面提到的這個動畫,看起來是拖動了藍色的view,其實是拖動了看不到的一個layer。。。
另:
iOS7已經提供了UIView的彈簧動畫:
+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay usingS
PRingWithDamping:(CGFloat)dampingRatio initialSpringVelocity:(CGFloat)velocity options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion NS_AVAILABLE_IOS(7_0);
但是像path動畫這種貌似還是得用keyFrameAnimation的方式來實現,具體就是要設置keyFrame動畫的幾個關鍵幀
keyFrameAnimation.values = @[(id)path1, (id)path2, (id)path3, (id)path4, (id)path5, (id)path1];
其中path1,path2。。。分別是那幾個關鍵幀的layer的具體的位置。
iOS7也提供了新的關鍵幀動畫api:
+ (void)animateKeyframesWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewKeyframeAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion NS_AVAILABLE_IOS(7_0);
+ (void)addKeyframeWithRelativeStartTime:(double)frameStartTime relativeDuration:(double)frameDuration animations:(void (^)(void))animations NS_AVAILABLE_IOS(7_0); // start time and duration are values between 0.0 and 1.0 specifying time and duration relative to the overall time of the keyframe animation
需要兩個方法配合使用,例子:
[UIViewanimateKeyframesWithDuration:0.25 delay:0 options:UIViewKeyframeAnimationOptionCalculationModeCubic animations:^{
[UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:2/3.0 animations:^{
self.label.transform = CGAffineTransformMakeScale(1.5, 1.5);
}];
[UIView addKeyframeWithRelativeStartTime:2/3.0 relativeDuration:1/3.0 animations:^{
self.label.transform=CGAffineTransformMakeScale(1.0,1.0);
}];
} completion:^(BOOL finished) {
}];
里面的方法是添加某一個關鍵幀,startTime和duration都是從0-1的相對與外面的Duration的時間,注意這兩個參數都是小數,直接1/2是不行的!!!