動畫(二) Code Animation 核心動畫

?一智嚷、核心動畫結(jié)構(gòu)及定義

? ? ? Code Animation 中文翻譯為核心動畫馍悟,它是一組非常強的的動畫處理API狮含,是以它能做出非常炫麗的動畫效果柒傻,且往往事半功倍

? ? 核心動畫所處的位置入下圖所示:


Core Animation 結(jié)構(gòu)

? ? ? 可以看到孝赫,Code Animation位于UIKit的下一層,是作用在CALayer(Core Animation layer)上红符,相較于UIView動畫寒锚,它可以實現(xiàn)更復雜的動畫效果。

?? ?下邊我們看一下违孝,核心動畫的幾個類及結(jié)構(gòu)


Code Animation類及結(jié)構(gòu)

下邊分析一下上圖結(jié)構(gòu):

**1.? CAMediaTiming** 協(xié)議中定義了時間,速度泳赋,重復次數(shù)等雌桑。屬性定義如下:

beginTime -> 用來設置動畫延時,若想延遲1秒祖今,就設置為CACurrentMediaTime()+1校坑,其中CACurrentMediaTime()為圖層當前時間拣技。

duration -> 動畫的持續(xù)時間。

speed -> 動畫速率耍目,決定動畫時間的倍率膏斤。當speed為2時,動畫時間為設置的duration的1/2邪驮。

timeOffset -> 動畫時間偏移量莫辨。比如設置動畫時長為3秒,當設置timeOffset為1.5時毅访,當前動畫會從中間位置開始沮榜,并在到達指定位置時,走完之前跳過的前半段動畫喻粹。

repeatCount -> 動畫的重復次數(shù)蟆融。

repeatDuration -> 動畫的重復時間。

autoreverses -> 動畫由初始值到最終值后守呜,是否反過來回到初始值的動畫型酥。如果設置為YES,就意味著動畫完成后會以動畫的形式回到初始值查乒。

fillMode -> 決定當前對象在非動畫時間段的行為.比如動畫開始之前弥喉,動畫結(jié)束之后。

(注:其實不只是CAAnimation遵循CAMediaTiming協(xié)議侣颂,熟悉底層結(jié)構(gòu)的小伙伴們應該知道CALayer也遵循這個協(xié)議档桃,所有在一定程度上我們可以通過控制layer本身的協(xié)議屬性來控制動畫節(jié)奏。)

**2. CAAnimation** 核心動畫基礎類憔晒,不能直接使用藻肄。除了CAMediaTiming協(xié)議中的方法,增加了CAAnimationDelegate的代理屬性等拒担。具體如下:

timingFunction -> 控制動畫的節(jié)奏嘹屯。系統(tǒng)提供的包括:kCAMediaTimingFunctionLinear (勻速),kCAMediaTimingFunctionEaseIn (慢進快出)从撼,kCAMediaTimingFunctionEaseOut (快進慢出)州弟,kCAMediaTimingFunctionEaseInEaseOut (慢進慢出,中間加速)低零,kCAMediaTimingFunctionDefault (默認)婆翔,當然也可通過自定義創(chuàng)建CAMediaTimingFunction。

delegate -> 代理掏婶。

removedOnCompletion -> 是否讓圖層保持顯示動畫執(zhí)行后的狀態(tài)啃奴,默認為YES,也就是動畫執(zhí)行完畢后從涂層上移除雄妥,恢復到執(zhí)行前的狀態(tài)最蕾,如果設置為NO依溯,并且設置fillMode為kCAFillModeForwards,則保持動畫執(zhí)行后的狀態(tài)瘟则。

**3. CATransition** 轉(zhuǎn)場動畫黎炉,系統(tǒng)提供了很多酷炫效果。屬性如下:

type -> 轉(zhuǎn)場動畫類型醋拧。

subtype -> 轉(zhuǎn)場動畫方向慷嗜。

startProgress -> 動畫起點進度(整體的百分比)。

endProgress -> 動畫終點進度(整體的百分比)趁仙。

filter -> 自定義轉(zhuǎn)場洪添。

**4.CAPropertyAnimation** 屬性動畫,針對對象的可動畫屬性進行效果的設置雀费,不可直接使用干奢。添加屬性具體如下:

keyPath -> CALayer的某個屬性名,并通過這個屬性的值進行修改盏袄,達到相應的動畫效果忿峻。

additive -> 屬性動畫是否以當前動畫效果為基礎,默認為NO辕羽。

cumulative -> 指定動畫是否為累加效果逛尚,默認為NO。

valueFunction -> 此屬性配合CALayer的transform屬性使用刁愿。

**5.CABasicAnimation**基礎動畫绰寞,通過keyPath對應屬性進行控制,需要設置fromValue以及toValue铣口。添加屬性如下:

fromValue -> keyPath相應屬性的初始值滤钱。

toValue -> keyPath相應屬性的結(jié)束值。

byValue -> 在不設置toValue時脑题,toValue = fromValue + byValue件缸,也就是在當前的位置上增加多少。

**6.CASpringAnimation** 帶有初始速度以及阻尼指數(shù)等物理參數(shù)的屬性動畫叔遂。我們可以把它看成在不絕對光滑的地面上他炊,一個彈簧拴著別小球,那么我們可以這么理解他的屬性(物理知識請問一下牛頓大叔):

mass -> 小球質(zhì)量已艰,影響慣性痊末。

stiffness -> 彈簧的勁度系數(shù)。

damping -> 阻尼系數(shù)哩掺,地面的摩擦力舌胶。

initialVelocity -> 初始速度,相當于給小球一個初始速度(可正可負疮丛,方向不同)

settlingDuration -> 結(jié)算時間幔嫂,根據(jù)上述參數(shù)計算出的預計時間,相對于你設置的時間誊薄,這個時間比較準確履恩。

**7.CAKeyframeAnimation** 關鍵幀動畫,同樣通過keyPath對應屬性進行控制呢蔫,但它可以通過values或者path進行多個階段的控制古涧。屬性如下:

values -> 關鍵幀組成的數(shù)組昨登,動畫會依次顯示其中的每一幀。

path -> 關鍵幀路徑,動畫進行的要素若皱,優(yōu)先級比values高,但是只對CALayer的anchorPoint和position起作用艘包。

keyTimes -> 每一幀對應的時間吊履,如果不設置,則各關鍵幀平分設定時間爷贫。

timingFunctions -> 每一幀對應的動畫節(jié)奏认然。

calculationMode -> 動畫的計算模式,系統(tǒng)提供了對應的幾種模式漫萄。

tensionValues -> 動畫張力控制卷员。

continuityValues -> 動畫連續(xù)性控制。

biasValues -> 動畫偏差率控制腾务。

rotationMode -> 動畫沿路徑旋轉(zhuǎn)方式毕骡,系統(tǒng)提供了兩種模式。

**8.CAAnimationGroup** 動畫組岩瘦,方便對于多動畫的統(tǒng)一控制管理未巫。

animations -> 所有動畫效果元素的數(shù)組。

?二 担钮、方法與代碼示例

**1橱赠、CABasicAnimation**

在一般的應用開發(fā)中,基礎動畫可以滿足大部分的開發(fā)需求箫津,主要完成對于對象指定動畫屬性兩個Value之間的動畫過度狭姨。

+(instancetype)animationWithKeyPath:(nullable NSString *)path;

**path:**CALayer的某個屬性名,并通過這個屬性的值進行修改苏遥,達到相應的動畫效果饼拍。下為可選參數(shù):

>? CATransform3D Key Paths :

> 旋轉(zhuǎn)

> transform.rotation.z

> rotation.x

> rotation.y

> rotation.z

> rotation

>

> 縮放

> scale.x

> scale.y

> scale.z

> scale

>

> 平移

> translation.x

> translation.y

> translation.z

> translation

>

> 位置

> CGPoint Key Paths:position.x

> x

> y

>

> 位置及大小

> CGRect Key Paths :

> bounds.size.width

> origin.x

> origin.y

> origin

> size.width

> size.height

> size

>?

> opacity 透明度

> backgroundColor 背景色

> cornerRadius? 圓角

> borderWidth? 邊距線寬

> contents? ? ? 內(nèi)容

>? ?

> 陰影

> Shadow Key Path:

>? shadowColor

>? shadowOffset

>? shadowOpacity

>? shadowRadius

代碼示例:

> -(void)basicAnimationWithTag:(NSInteger)tag{

>? ? CABasicAnimation *basicAni = nil;

>? ? switch (tag) {

>? ? ? ? case 0:

>? ? ? ? ? ? //初始化動畫并設置keyPath

>? ? ? ? ? ? basicAni = [CABasicAnimation animationWithKeyPath:@"position"];

>? ? ? ? ? ? //到達位置

>? ? ? ? ? ? basicAni.byValue = [NSValue valueWithCGPoint:CGPointMake(100, 100)];

>? ? ? ? ? ? break;

>? ? ? ? case 1:

>? ? ? ? ? ? basicAni = [CABasicAnimation animationWithKeyPath:@"transform.scale"];

>? ? ? ? ? ? //到達縮放

>? ? ? ? ? ? basicAni.toValue = @(0.1f);

>? ? ? ? ? ? break;

>? ? ? ? case 2:

>? ? ? ? ? ? basicAni = [CABasicAnimation animationWithKeyPath:@"opacity"];

>? ? ? ? ? ? basicAni.toValue=@(0.1f);

>? ? ? ? ? ? break;

>? ? ? ? case 3:

>? ? ? ? ? ? basicAni = [CABasicAnimation animationWithKeyPath:@"transform"];

>? ? ? ? ? ? //3D

>? ? ? ? ? ? basicAni.toValue=[NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI_2+M_PI_4, 1, 1, 0)];

>? ? ? ? ? ? break;

>? ? ? ? case 4:

>? ? ? ? ? ? basicAni = [CABasicAnimation animationWithKeyPath:@"cornerRadius"];

>? ? ? ? ? ? //圓角

>? ? ? ? ? ? basicAni.toValue=@(50);

>? ? ? ? ? ? break;

>? ? ? ? default:

>? ? ? ? ? ? break;

>? ? }

>? ? //設置代理

>? ? basicAni.delegate = self;

>? ? //延時執(zhí)行

>? ? //basicAni.beginTime = CACurrentMediaTime() + 2;

>? ? //動畫時間

>? ? basicAni.duration = 1;

>? ? //動畫節(jié)奏

>? ? basicAni.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

>? ? //動畫速率

>? ? //basicAni.speed = 0.1;

>? ? //圖層是否顯示執(zhí)行后的動畫執(zhí)行后的位置以及狀態(tài)

>? ? //basicAni.removedOnCompletion = NO;

>? ? //basicAni.fillMode = kCAFillModeForwards;

>? ? //動畫完成后是否以動畫形式回到初始值

>? ? basicAni.autoreverses = YES;

>? ? //動畫時間偏移

>? ? //basicAni.timeOffset = 0.5;

>? ? //添加動畫

>? ? NSString *key = NSStringFromSelector(_cmd);

>? ? NSLog(@"動畫的key ======= %@",key);

>? ? [_animationLayer addAnimation:basicAni forKey:key];

> }

**2、CASpringAnimation**

CASpringAnimation是iOS9才引入的動畫類田炭,效果類似于UIView的spring動畫师抄,不過比其增加了質(zhì)量,勁度系數(shù)等屬性的擴展教硫,繼承于CABaseAnimation叨吮,用法也很簡單:

>? CASpringAnimation *springAni = [CASpringAnimation animationWithKeyPath:@"position"];

>? ? springAni.damping = 2;

>? ? springAni.stiffness = 50;

>? ? springAni.mass = 1;

>? ? springAni.initialVelocity = 2;

>? ? springAni.toValue = [NSValue valueWithCGPoint:CGPointMake(270, 350)];

>? ? springAni.duration = springAni.settlingDuration;

>? ? [_animationLayer addAnimation:springAni forKey:@"springAnimation"];

**3.CAKeyframeAnimation**

關鍵幀動畫和CABasicAnimation一樣是CApropertyAnimation的子類辆布,但是CABasicAnimation只能從一個數(shù)值(fromValue)變到另一個數(shù)值(toValue),而CAKeyframeAnimation使用values數(shù)組可以通過(keyTimes)設置多個關鍵幀茶鉴,同時可以利用path可以進行位置或者錨點的動畫操作锋玲。代碼如下

通過values設置

>? CAKeyframeAnimation *keyFrameAni = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];

> keyFrameAni.duration = 2;

> keyFrameAni.values = @[@(-(6) / 180.0*M_PI),@((6) / 180.0*M_PI),@(-(5) / 180.0*M_PI),@((5) / 180.0*M_PI),@(-(4) / 180.0*M_PI),@((4) / 180.0*M_PI),@(-(4) / 180.0*M_PI)];

> keyFrameAni.keyTimes = @[ @(0), @(0.225), @(0.425), @(0.6), @(0.75), @(0.875), @(1)];

> keyFrameAni.repeatCount = 2;

> [_animationLayer addAnimation:keyFrameAni forKey:@"keyFrameAnimation"];

通過path設置

? ? CAKeyframeAnimation *keyFrameAni = [CAKeyframeAnimation animationWithKeyPath:@"position"];

? ? UIBezierPath *path = [UIBezierPath bezierPath];

? ? [path moveToPoint:_animationLayer.position;

? ? [path addCurveToPoint:CGPointMake(300, 500) controlPoint1:CGPointMake(100, 400) controlPoint2:CGPointMake(270, 460)];

? ? keyFrameAni.path = path.CGPath;

? ? keyFrameAni.duration = 1;

? ? [_animationLayer addAnimation:keyFrameAni forKey:@"keyFrameAnimation"];

**4.CATransition**

轉(zhuǎn)場動畫是一種顯示樣式向另一種顯示樣式過渡的效果,能制作出酷炫的效果涵叮,不過謹慎使用私有API惭蹂,防止被拒的悲劇。

>? ? **type的enum值如下:**

>? ? kCATransitionFade 漸變

>? ? kCATransitionMoveIn 覆蓋

>? ? kCATransitionPush 推出

>? ? kCATransitionReveal 揭開

還有一些私有動畫類型割粮,效果很炫酷盾碗,不過不推薦使用。


轉(zhuǎn)場動畫效果

subtype可取值:

>? ? **subtype的enum值如下:**

>? ? kCATransitionFromRight 從右邊

>? ? kCATransitionFromLeft 從左邊

>? ? kCATransitionFromTop 從頂部

>? ? kCATransitionFromBottom 從底部

代碼示例

>? ? ? CATransition *transtion = [CATransition animation];

>? ? transtion.duration = 1;

>? ? transtion.type = @"cube";

>? ? transtion.subtype = kCATransitionFromRight;//kCATransitionFromLeft? kCATransitionFromRight

>? ? _animationLayer.backgroundColor = [UIColor yellowColor].CGColor;

>? ? [_animationLayer addAnimation:transtion forKey:@"transtion"];

**5.CAAnimationGroup**

CAAnimationGroup 是一個動畫組舀瓢,使用Group可以將多個動畫合并一起加入到層中廷雅,Group中所有動畫并發(fā)執(zhí)行,可以方便地實現(xiàn)需要多種類型動畫的場景氢伟。

代碼示例

? ? //彈動動畫

? ? CAKeyframeAnimation *keyFrameAni = [CAKeyframeAnimation animationWithKeyPath:@"position.y"];

? ? CGFloat ty = _animationLayer.position.y;

? ? keyFrameAni.values = @[@(ty - 100),@(ty),@(ty - 50),@(ty)];

? ? //每一個動畫可以單獨設置時間和重復次數(shù),在動畫組的時間基礎上,控制單動畫的效果

? ? keyFrameAni.duration = 0.3;

? ? keyFrameAni.repeatCount= MAXFLOAT;

? ? keyFrameAni.delegate = self;

? ? //

? ? //圓角動畫

? ? CABasicAnimation *basicAni = [CABasicAnimation animationWithKeyPath:@"cornerRadius"];

? ? //到達位置

? ? basicAni.byValue = @(_animationLayer.bounds.size.width/2);

? ? //

? ? basicAni.duration = 1;

? ? basicAni.repeatCount = 1;

? ? //

? ? basicAni.removedOnCompletion = NO;

? ? basicAni.fillMode = kCAFillModeForwards;

? ? //設置代理

? ? basicAni.delegate = self;

? ? //動畫時間

? ? basicAni.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

? ? CAAnimationGroup *aniGroup = [CAAnimationGroup animation];

? ? aniGroup.animations = @[keyFrameAni,basicAni];

? ? aniGroup.autoreverses = YES;

? ? //動畫的表現(xiàn)時間和重復次數(shù)由動畫組設置的決定

? ? aniGroup.duration = 3;

? ? aniGroup.repeatCount=MAXFLOAT;

? ? //

? ? [_animationLayer addAnimation:aniGroup forKey:@"groupAnimation"];


三榜轿、動畫的暫停、恢復朵锣、加快及移除動畫

1谬盐、speed屬性是指當前層動畫的速率。用于將父時間縮放到本地時間诚些,例如飞傀。

如果速率為2,則本地時間的進展速度是父時間的兩倍诬烹。

我們可以通過設置speed =0來暫停動畫:

代碼示例:

?//獲取當前l(fā)ayer的動畫媒體時間

? ? CFTimeInterval interval = [_animationLayer convertTime:CACurrentMediaTime() toLayer:nil];

? ? //設置時間偏移量,保證停留在當前位置

? ? _animationLayer.timeOffset= interval;

? ? //暫定動畫

? ? _animationLayer.speed = 0;

設置speed =1來恢復動畫

代碼示例:

?//獲取暫停的時間

? ? CFTimeInterval beginTime = CACurrentMediaTime() - _animationLayer.timeOffset;

? ? //設置偏移量

? ? _animationLayer.timeOffset = 0;

? ? //設置開始時間

? ? _animationLayer.beginTime= beginTime;

? ? //開始動畫

? ? _animationLayer.speed = 1;

設置speed >1來加速動畫

代碼示例:

?_animationLayer.speed = 2;


2砸烦、動畫結(jié)束,我們可以移除動畫

[_animationLayer removeAllAnimations];//移除當前層所有動畫

? ? //[_animationLayer removeAnimationForKey:@"groupAnimation"];//移除當前層上名稱是groupAnimation的動畫

? 關于Code Animation 绞吁,就寫到這里了幢痘,附demo一份GitHub - Tony-iOS-Personal/AnimationDemo: 關于動畫的總結(jié)demo

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市家破,隨后出現(xiàn)的幾起案子颜说,更是在濱河造成了極大的恐慌,老刑警劉巖汰聋,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件门粪,死亡現(xiàn)場離奇詭異,居然都是意外死亡烹困,警方通過查閱死者的電腦和手機玄妈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人拟蜻,你說我怎么就攤上這事绎签。” “怎么了瞭郑?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵辜御,是天一觀的道長。 經(jīng)常有香客問我屈张,道長,這世上最難降的妖魔是什么袱巨? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任阁谆,我火速辦了婚禮,結(jié)果婚禮上愉老,老公的妹妹穿的比我還像新娘场绿。我一直安慰自己,他們只是感情好嫉入,可當我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布焰盗。 她就那樣靜靜地躺著,像睡著了一般咒林。 火紅的嫁衣襯著肌膚如雪熬拒。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天垫竞,我揣著相機與錄音澎粟,去河邊找鬼。 笑死欢瞪,一個胖子當著我的面吹牛活烙,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播遣鼓,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼啸盏,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了骑祟?” 一聲冷哼從身側(cè)響起回懦,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎曾我,沒想到半個月后粉怕,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡抒巢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年贫贝,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡稚晚,死狀恐怖崇堵,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情客燕,我是刑警寧澤鸳劳,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站也搓,受9級特大地震影響赏廓,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜傍妒,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一幔摸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧颤练,春花似錦既忆、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至宇挫,卻和暖如春苛吱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背捞稿。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工又谋, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人娱局。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓彰亥,卻偏偏與公主長得像,于是被迫代替她去往敵國和親衰齐。 傳聞我的和親對象是個殘疾皇子任斋,可洞房花燭夜當晚...
    茶點故事閱讀 44,724評論 2 354

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