CALayer
CALayer是個與UIView很類似的概念,同樣有l(wèi)ayer,sublayer...,同樣有backgroundColor、frame等相似的屬性,我們可以將UIView看做一種特殊的CALayer,只不過UIView可以響應(yīng)事件而已。一般來說,layer可以有兩種用途,二者不互相沖突:一是對view相關(guān)屬性的設(shè)置,包括圓角、陰影、邊框等參數(shù),更詳細的參數(shù)請點擊這里;二是實現(xiàn)對view的動畫操控。因此對一個view進行core animation動畫,本質(zhì)上是對該view的.layer進行動畫操縱。
CAAnimation
CAAnimation可分為四種:
1. CABasicAnimation 基本動畫
通過設(shè)定起始點,終點,時間,動畫會沿著你這設(shè)定點進行移動??梢钥醋鎏厥獾腃AKeyFrameAnimation
創(chuàng)建cabaseanimation 的方法,但是在最新的apple開發(fā)文檔沒有查到path到底有哪些,網(wǎng)上搜羅了一下,并猜測path跟layer中的屬性字段是一致的如background
/\*\* Subclass for property-based animations. \*\*/
@interface CAPropertyAnimation : CAAnimation
/\* Creates a new animation object with its `keyPath' property set to \* 'path'. \*/
+ (instancetype)animationWithKeyPath:(nullable NSString *)path;
/\* The key-path describing the property to be animated. \*/
@property(nullable, copy) NSString *keyPath;
path用途
rotaion.x旋轉(zhuǎn),弧度,X軸
rotaion.y旋轉(zhuǎn),弧度,Y軸
rotaion.z旋轉(zhuǎn),弧度,Z軸
rotaion旋轉(zhuǎn),弧度,Z軸,完全等同于rotation.z
scale.x縮放,X軸
scale.y縮放,Y軸
scale.z縮放,Z軸
scale縮放,XYZ軸
translation.x移動,X軸
translation.y移動,Y軸
translation.z移動,Z軸
translation移動,XY軸,value值為NSSize或者CGSize類型
opacity等zPosition、frame、backgroundColor、cornerRadius類似的layer中的各種屬性
所以有如下代碼
????/\*\* \* 透明度動畫 \*/
-(void)opacityAniamtion{
CABasicAnimation *anima = [CABasicAnimation animationWithKeyPath:@"opacity"];
anima.fromValue = [NSNumber numberWithFloat:1.0f];
anima.toValue = [NSNumber numberWithFloat:0.2f];
anima.duration = 1.0f;
[_demoView.layer addAnimation:anima forKey:@"opacityAniamtion"];
}
/\*\* \* 縮放動畫 \*/
-(void)scaleAnimation{
CABasicAnimation *anima = [CABasicAnimation animationWithKeyPath:@"transform.scale"];//同上
anima.toValue = [NSNumber numberWithFloat:2.0f];
anima.duration = 1.0f;
[_demoView.layer addAnimation:anima forKey:@"scaleAnimation"];
}
/\*\* \* 旋轉(zhuǎn)動畫 \*/
-(void)rotateAnimation{
CABasicAnimation *anima = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];//繞著z軸為矢量,進行旋轉(zhuǎn)(@"transform.rotation.z"==@@"transform.rotation")
anima.toValue = [NSNumber numberWithFloat:3*M_PI];
anima.duration = 1.0f;
[_demoView.layer addAnimation:anima forKey:@"rotateAnimation"];
}
/\*\* \* 背景色變化動畫 \*/
-(void)backgroundAnimation{
CABasicAnimation *anima = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
anima.toValue =(id) [UIColor greenColor].CGColor;
anima.duration = 1.0f;
[_demoView.layer addAnimation:anima forKey:@"backgroundAnimation"];
}
有人會疑惑addanimation:forkey: 這個key到底是什么官方的注釋是
/\*\* Animation methods. \*\*/
/\* Attach an animation object to the layer. Typically this is implicitly \* invoked through an action that is an CAAnimation object. \* \* 'key' may be any string such that only one animation per unique key \* is added per layer. The special key 'transition' is automatically \* used for transition animations. The nil pointer is also a valid key. \* \* If the `duration' property of the animation is zero or negative it \* is given the default duration, either the value of the \* `animationDuration' transaction property or .25 seconds otherwise. \* \* The animation is copied before being added to the layer, so any \* subsequent modifications to `anim' will have no affect unless it is \* added to another layer. \*/
翻譯下
/ \* \*動畫方法。\* \* //
\* 將動畫對象附加到層。通常這是隱式地
\* 通過一個動作是一個CAAnimation對象調(diào)用。
\* “key”可以是任何字符串,這樣每個唯一鍵只有一個動畫
\* 添加每層。特殊鍵自動“過渡”
\* 用于過渡動畫??罩羔樢彩且粋€有效的關(guān)鍵。
\* 如果動畫的“持續(xù)時間”屬性是零或消極
\* 默認時間,給出的值
\* animationDuration事務(wù)屬性或。25秒。
\* 動畫復(fù)制之前添加到層,所以任何后續(xù)修改“動畫”沒有影響,除非它是添加到另一層
所以大家放心使用CABasicAnimation!
2. CAKeyframeAnimation 關(guān)鍵幀動畫
Keyframe顧名思義就是關(guān)鍵點的frame,你可以通過設(shè)定CALayer的始點、中間關(guān)鍵點、終點的frame,時間,動畫會沿你設(shè)定的軌跡進行移動 CAKeyframeAnimation 的一些比較重要的屬性
2.1. path
這是一個 CGPathRef 對象,默認是空的,當(dāng)我們創(chuàng)建好CAKeyframeAnimation的實例的時候,可以通過制定一個自己定義的path來讓某一個物體按照這個路徑進行動畫。這個值默認是nil,當(dāng)其被設(shè)定的時候values 這個屬性就被覆蓋。
2.2. values
一個數(shù)組,提供了一組關(guān)鍵幀的值,當(dāng)使用path的 時候 values的值自動被忽略。
下面是一個簡單的例子 效果為動畫的連續(xù)移動一個block到不同的位置
/\*\* \* 關(guān)鍵幀動畫 values \*/
-(void)keyFrameAnimation{
CAKeyframeAnimation *anima = [CAKeyframeAnimation animationWithKeyPath:@"position"];
NSValue *value0 = [NSValue valueWithCGPoint:CGPointMake(0, SCREEN_HEIGHT/2-50)];
NSValue *value1 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2-50)];
NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2+50)];
NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH*2/3, SCREEN_HEIGHT/2+50)];
NSValue *value4 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH*2/3, SCREEN_HEIGHT/2-50)];
NSValue *value5 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH, SCREEN_HEIGHT/2-50)];
anima.values = [NSArray arrayWithObjects:value0,value1,value2,value3,value4,value5, nil];
anima.duration = 2.0f;
anima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];//設(shè)置動畫的節(jié)奏
anima.delegate = self;//設(shè)置代理,可以檢測動畫的開始和結(jié)束
[_demoView.layer addAnimation:anima forKey:@"keyFrameAnimation"];
}
/\*\* \* path動畫 \*/
-(void)pathAnimation{
CAKeyframeAnimation *anima = [CAKeyframeAnimation animationWithKeyPath:@"position"];
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(SCREEN_WIDTH/2-100, SCREEN_HEIGHT/2-100, 200, 200)];
anima.path = path.CGPath;
anima.duration = 2.0f;
[_demoView.layer addAnimation:anima forKey:@"pathAnimation"];
}
對比UIView動畫跟關(guān)鍵幀動畫,關(guān)鍵幀動畫引入了動畫占比時長的概念,這讓我們能控制每個關(guān)鍵幀動畫的占用比例而不是傳入一個無意義的動畫時長 —— 這讓我們的代碼更加難以理解。當(dāng)然,除了動畫占比之外,關(guān)鍵幀動畫的options參數(shù)也讓動畫變得更加平滑,下面是關(guān)鍵幀特有的配置參數(shù):
UIViewKeyframeAnimationOptionCalculationModeLinear // 連續(xù)運算模式,線性
UIViewKeyframeAnimationOptionCalculationModeDiscrete // 離散運算模式,只顯示關(guān)鍵幀
UIViewKeyframeAnimationOptionCalculationModePaced // 均勻執(zhí)行運算模式,線性
UIViewKeyframeAnimationOptionCalculationModeCubic // 平滑運算模式
UIViewKeyframeAnimationOptionCalculationModeCubicPaced // 平滑均勻運算模式
3. CAAnimationGroup 組合動畫
- Group也就是組合的意思,可以保存一組動畫對象,將CAAnimationGroup對象加入圖層后,組中所有動畫對象可以同時并發(fā)運行
- animations屬性:用來保存一組動畫對象的NSArray
- 注意:默認情況下,一組動畫對象是同時運行的,也 可以通過設(shè)置動畫對象的beginTime屬性來更改動畫的開始時間
-(void)groupAnimation1{
// //位移動畫
CAKeyframeAnimation *anima1 = [CAKeyframeAnimation animationWithKeyPath:@"position"];
NSValue *value0 = [NSValue valueWithCGPoint:CGPointMake(0, SCREEN_HEIGHT/2-50)];
NSValue *value1 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2-50)];
NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2+50)];
NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH*2/3, SCREEN_HEIGHT/2+50)];
NSValue *value4 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH*2/3, SCREEN_HEIGHT/2-50)];
NSValue *value5 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH, SCREEN_HEIGHT/2-50)];
anima1.values = [NSArray arrayWithObjects:value0,value1,value2,value3,value4,value5, nil];
//縮放動畫
CABasicAnimation *anima2 = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
anima2.fromValue = [NSNumber numberWithFloat:0.8f];
anima2.toValue = [NSNumber numberWithFloat:2.0f];
//旋轉(zhuǎn)動畫
CABasicAnimation *anima3 = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
anima3.toValue = [NSNumber numberWithFloat:M_PI*4];
//組動畫
CAAnimationGroup *groupAnimation = [CAAnimationGroup animation];
groupAnimation.animations = [NSArray arrayWithObjects:anima1,anima2,anima3, nil];
groupAnimation.duration = 4.0f;
[_demoView.layer addAnimation:groupAnimation forKey:@"groupAnimation"];
}
組合動畫
PS:一個layer設(shè)定了很多動畫,他們都會同時執(zhí)行,而且是順序執(zhí)行。(詳見demo)
4. CATransition 系統(tǒng)封裝的過渡動畫
- 對于UIView的動畫
UIViewAnimationTransition 聲明過渡方向UIViewAnimationTransitionFlipFromLeft向左轉(zhuǎn)動UIViewAnimationTransitionFlipFromRight向右轉(zhuǎn)動UIViewAnimationTransitionCurlUp向上翻動UIViewAnimationTransitionCurlDown向下翻動
//寫法一
-(void)test
{
[UIView beginAnimations:@"animationID" context:nil];
[UIView setAnimationDuration:0.5f]; //動畫時長
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.view cache:YES]; //給視圖添加過渡效果
//在這里寫你的代碼.
[UIView commitAnimations]; //提交動畫
}
\#pragma UIView實現(xiàn)動畫
- (void) animationWithView : (UIView *)view WithAnimationTransition : (UIViewAnimationTransition) transition
{
[UIView animateWithDuration:DURATION animations:^{
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:transition forView:view cache:YES];
}];
}
- 對于layer的動畫
名稱 CATransition.type過渡效果kCATransitionFade//淡入淡出 (不支持過渡方向)kCATransitionPush,//推擠kCATransitionReveal//揭開kCATransitionMoveIn//覆蓋Cube//立方體SuckEffect//吮吸OglFlip//翻轉(zhuǎn)rippleEffect//波紋pageCurl//翻頁pageUnCurl//反翻頁cameraIrisHollowOpen//開鏡頭 相機鏡頭打開效果(不支持過渡方向)cameraIrisHollowClose//關(guān)鏡頭 相機鏡頭打開效果(不支持過渡方向)
CATransition含有type和subtype兩個屬性,分別的解釋是
/* The name of the transition. Current legal transition types include
fade',moveIn',push' andreveal'. Defaults to `fade'. */
@property(copy) NSString *type;/* An optional subtype for the transition. E.g. used to specify the
- transition direction for motion-based transitions, in which case
- the legal values are
fromLeft',fromRight', `fromTop' and- `fromBottom'. */
@property(nullable, copy) NSString *subtype;
由此可見設(shè)置CATransition動畫就是動畫效果和方向的結(jié)合
//寫法二
\#pragma CATransition動畫實現(xiàn)
- (void) transitionWithType:(NSString *) type WithSubtype:(NSString *) subtype ForView : (UIView *) view
{
//創(chuàng)建CATransition對象
CATransition *animation = [CATransition animation];
//設(shè)置運動時間
animation.duration = DURATION;
//設(shè)置運動type
animation.type = type;
if (subtype != nil) {
//設(shè)置子類
animation.subtype = subtype;
}
//設(shè)置運動速度
animation.timingFunction = UIViewAnimationOptionCurveEaseInOut;
[view.layer addAnimation:animation forKey:@"animation"];
}