iOS開發(fā)-CoreAnimation

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"];
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容