iOS動畫—— Core Animation

一. Core Animation類簡介

  • Core Animation,譯為核心動畫,是蘋果提供的非常強大的動畫處理API
  • Core Animation的動畫執(zhí)行過程都是在后臺操作的,不會阻塞主線程宴倍。
  • Core Animation是作用于CALayer上的動畫张症,每一個繼承與UIView的子類都有一個layer屬性,可以通過這個layer來為更改相應(yīng)view的形式啊楚,或者做動畫吠冤。
  • Core Animation框架是基于OpenGL與CoreGraphics圖像處理框架的一個跨平臺的動畫框架。將圖像讀取成位圖恭理,通過硬件的處理拯辙,實現(xiàn)動畫效果
1. CoreAnimation與UIKit框架的關(guān)系
2. Core Animation類的繼承關(guān)系圖

在CoreAnimation中,大部分的動畫效果都是通過Layer層來實現(xiàn)的,通過CALayer涯保,我們可以組織復(fù)雜的層級結(jié)構(gòu)诉濒。Layer層并不決定視圖的展現(xiàn),它只是存儲了視圖的幾何屬性狀態(tài)

3. 錨點對幾何屬性的影響
@property CGPoint anchorPoint;  
@property CGPoint position;  
  • position:它是用來設(shè)置當(dāng)前的layer在父控件當(dāng)中的位置的.
    所以它的坐標(biāo)原點.以父控件的左上角為(0.0)點.
  • anchorPoint: "錨點"夕春,取值范圍都是0~1未荒,默認值為(0.5, 0.5)。決定著CALayer身上的哪個點會在position屬性所指的位置

position與anchorPoint關(guān)系


position和anchorPoint(1).png
position和anchorPoint(2).png

二. CABasicAnimation

CAAnimation
//動畫速度
@property(nullable, strong) CAMediaTimingFunction *timingFunction;
kCAMediaTimingFunctionLinear  線性及志,勻速
kCAMediaTimingFunctionEaseIn  漸進片排,逐漸進入,然后加速完成
kCAMediaTimingFunctionEaseOut 漸出速侈,動畫全速進入率寡,然后緩慢完成
kCAMediaTimingFunctionEaseInEaseOut  漸進漸出

//默認為YES,代表動畫執(zhí)行完畢后就從圖層上移除倚搬,圖形會恢復(fù)到動畫執(zhí)行前的狀態(tài)冶共。
//如果想讓圖層保持顯示動畫執(zhí)行后的狀態(tài),那就設(shè)置為NO每界,不過還要設(shè)置fillMode
@property(getter=isRemovedOnCompletion) BOOL 
CAMediaTiming

CAMediaTimingCAAnimation遵守的協(xié)議

beginTime   動畫的開始時間(如果超過的duration捅僵,那么動畫不會開始)
duration    動畫的持續(xù)時間
speed       動畫的速度
repeatCount 重復(fù)次數(shù),默認為0眨层,無限重復(fù)可以設(shè)置為HUGE_VALF或者MAXFLOAT
repeatDuration 動畫重復(fù)時間庙楚,默認為0
fillMode     決定當(dāng)前對象在非active時間段的行為。(要想fillMode有效谐岁,最好設(shè)置removedOnCompletion = NO)

fillMode類型:
    kCAFillModeRemoved     這個是默認值醋奠,也就是說當(dāng)動畫開始前和動畫結(jié)束后,動畫對layer都沒有影響伊佃,動畫結(jié)束后窜司,layer會恢復(fù)到之前的狀態(tài)
    kCAFillModeForwards    當(dāng)動畫結(jié)束后,layer會一直保持著動畫最后的狀態(tài)
    kCAFillModeBackwards   在動畫開始前航揉,只需要將動畫加入了一個layer塞祈,layer便立即進入動畫的初始狀態(tài)并等待動畫開始。
    kCAFillModeBoth        這個其實就是上面兩個的合成,動畫加入后開始之前帅涂,layer便處于動畫初始狀態(tài)议薪,動畫結(jié)束后layer保持動畫最后的狀態(tài)
CAAnimationDelegate 代理
// 動畫開始的時候調(diào)用
- (void)animationDidStart:(CAAnimation *)anim;
// 動畫停止的時候調(diào)用
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;
CABasicAnimation

1.創(chuàng)建動畫
2.設(shè)置相關(guān)屬性
3.將動畫添加到某個layer

// 創(chuàng)建動畫  Layer的屬性作為關(guān)鍵路徑進行注冊。
+ (instancetype)animationWithKeyPath:(nullable NSString *)path;
// 添加動畫
- (void)addAnimation:(CAAnimation *)anim forKey:(nullable NSString *)key;
// 移除動畫
- (void)removeAnimationForKey:(NSString *)key;
- (void)removeAllAnimations;

keyPath 為CALayer的屬性值媳友,并對它的值進行修改斯议,以達到對應(yīng)的動畫效果,需要注意的是部分屬性值是不支持動畫效果的醇锚。

transform.scale (比例轉(zhuǎn)換)哼御、
transform.scale.x
transform.scale.y
transform.rotation.z

 transform.rotation   (旋轉(zhuǎn)) 
transform.rotation.x  (繞x軸旋轉(zhuǎn))
transform.rotation.y  (繞y軸旋轉(zhuǎn))
transform.rotation.z  (繞z軸旋轉(zhuǎn))

opacity  (透明度)
margin  布局
backgroundColor  (背景色)
cornerRadius   (圓角)
borderWidth  (邊框?qū)?
bounds   (大小)
frame  (大小位置)
hidden (顯示隱藏)

contents    (內(nèi)容)
contentsRect  (內(nèi)容大小)
cornerRadius (大小)
mask
masksToBounds

shadowColor(陰影色)坯临、
shadowOffset
shadowOpacity
shadowOpacity

動畫的起始與結(jié)束位置

//  指定屬性(keyPath)開始的值
@property(nullable, strong) id fromValue;
// 指定屬性結(jié)束時的值
@property(nullable, strong) id toValue;
// 在原有的值上改變
@property(nullable, strong) id byValue;
  • fromValuetoValue不為空:動畫的值由fromValue變化到toValue

  • fromValuebyValue不為空:動畫的值由fromValue變化到fromValue+byValue

  • byValuetoValue不為空:動畫的值由toValue-byValue變化到toValue

  • 只有fromValue不為空:動畫的值由fromValue變化到layer的當(dāng)前狀態(tài)值

  • 只有toValue不為空:動畫的值由layer當(dāng)前的值變化到toValue

  • 只有byValue不為空:動畫的值由layer當(dāng)前的值變化到layer當(dāng)前的值+byValue

CABasicAnimation可以設(shè)定keyPath的起點,終點的值恋昼,動畫會沿著設(shè)定點進行移動看靠,CABasicAnimation可以看成是只有兩個關(guān)鍵點的特殊的CAKeyFrameAnimation。

演示
- (void)position {
    CABasicAnimation * ani = [CABasicAnimation animationWithKeyPath:@"position"];
    ani.toValue = [NSValue valueWithCGPoint:self.centerShow.center];
    ani.removedOnCompletion = NO;
    ani.fillMode = kCAFillModeForwards;
    ani.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [self.cartCenter.layer addAnimation:ani forKey:@"PostionAni"];
}

CAAnimationGroup 組動畫

CAAnimationGroup可以保存一組動畫對象(比如可以把前面的2中動畫結(jié)合起來)液肌,將CAAnimationGroup對象加入層后挟炬,組中所有動畫對象可以同時并發(fā)運行。也可以讓動畫按照時間依次串行

/// 依次串行
-(void)animationGroup3{
    CFTimeInterval currentTime = CACurrentMediaTime();
    //位移動畫
    CABasicAnimation *anima1 = [CABasicAnimation animationWithKeyPath:@"position"];
    anima1.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, SCREEN_HEIGHT/2-75)];
    anima1.toValue = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/2, SCREEN_HEIGHT/2-75)];
    anima1.beginTime = currentTime;
    anima1.duration = 1.0f;
    anima1.fillMode = kCAFillModeForwards;
    anima1.removedOnCompletion = NO;
    [_animationLayer addAnimation:anima1 forKey:@"aa"];
    //縮放動畫
    CABasicAnimation *anima2 = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
    anima2.fromValue = [NSNumber numberWithFloat:0.8f];
    anima2.toValue = [NSNumber numberWithFloat:2.0f];
    anima2.beginTime = currentTime+1.0f;
    anima2.duration = 1.0f;
    anima2.fillMode = kCAFillModeForwards;
    anima2.removedOnCompletion = NO;
    [_animationLayer addAnimation:anima2 forKey:@"bb"];
    //旋轉(zhuǎn)動畫
    CABasicAnimation *anima3 = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
    anima3.toValue = [NSNumber numberWithFloat:M_PI*4];
    anima3.beginTime = currentTime+2.0f;
    anima3.duration = 1.0f;
    anima3.fillMode = kCAFillModeForwards;
    anima3.removedOnCompletion = NO;
    [_animationLayer addAnimation:anima3 forKey:@"cc"];
}
截屏2022-04-29 15.57.37.png

CAKeyframeAnimation 關(guān)鍵幀動畫

CABasicAnimation 不同的是CAKeyframeAnimation會使用一個NSArray保存一組關(guān)鍵幀嗦哆,而且通過繪圖來指定路徑谤祖。而CABasicAnimation只能從一個數(shù)值(fromValue)變換成另一個數(shù)值(toValue

-(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"];
}

Demo

GitHub: https://github.com/iOSlixiang/Animations.git

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末老速,一起剝皮案震驚了整個濱河市泊脐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌烁峭,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件秕铛,死亡現(xiàn)場離奇詭異约郁,居然都是意外死亡,警方通過查閱死者的電腦和手機但两,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進店門鬓梅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人谨湘,你說我怎么就攤上這事绽快。” “怎么了紧阔?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵坊罢,是天一觀的道長。 經(jīng)常有香客問我擅耽,道長活孩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任乖仇,我火速辦了婚禮憾儒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘乃沙。我一直安慰自己起趾,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布警儒。 她就那樣靜靜地躺著训裆,像睡著了一般慈参。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上骇塘,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天捉片,我揣著相機與錄音,去河邊找鬼艺骂。 笑死诸老,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的钳恕。 我是一名探鬼主播别伏,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼忧额!你這毒婦竟也來了厘肮?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤睦番,失蹤者是張志新(化名)和其女友劉穎类茂,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體托嚣,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡巩检,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了示启。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片兢哭。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖夫嗓,靈堂內(nèi)的尸體忽然破棺而出迟螺,到底是詐尸還是另有隱情,我是刑警寧澤舍咖,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布矩父,位于F島的核電站,受9級特大地震影響排霉,放射性物質(zhì)發(fā)生泄漏浙垫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一郑诺、第九天 我趴在偏房一處隱蔽的房頂上張望夹姥。 院中可真熱鬧,春花似錦辙诞、人聲如沸辙售。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽旦部。三九已至祈搜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間士八,已是汗流浹背容燕。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留婚度,地道東北人蘸秘。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像蝗茁,于是被迫代替她去往敵國和親醋虏。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容