細(xì)說(shuō)CoreAnimation

封面.jpg

前言:

核心動(dòng)畫是iOS中一個(gè)渲染和動(dòng)畫的基礎(chǔ)設(shè)施行拢,你可以用它來(lái)為你的應(yīng)用做基礎(chǔ)的動(dòng)畫效果。在核心動(dòng)畫中邢享,你要做的只是配置一些動(dòng)畫參數(shù)始衅,接下來(lái)的任務(wù)就可以交給核心動(dòng)畫來(lái)處理了,很方便是吧议双。下面是核心動(dòng)畫在系統(tǒng)的層次結(jié)構(gòu):


1.png

CoreAnimation

CAAnimation 是一個(gè)抽象的動(dòng)畫類痘番,他提供基本的支持給CAMediaTimingCAAction。給Layer添加動(dòng)畫,你也可以使用子類CABasicAnimation,CAKeyframeAnimation, CAAnimationGroup, 和 CATransition.

2.png

CAAnimation

CAMediaTimingFunction
是一個(gè)控制動(dòng)畫節(jié)奏的可選的時(shí)間函數(shù)汞舱。它的初始化以下面的初始化方式構(gòu)造對(duì)象:

+ (instancetype)functionWithName:(NSString *)name;
/** Timing function names. **/

CA_EXTERN NSString * const kCAMediaTimingFunctionLinear
    __OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
CA_EXTERN NSString * const kCAMediaTimingFunctionEaseIn
    __OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
CA_EXTERN NSString * const kCAMediaTimingFunctionEaseOut
    __OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
CA_EXTERN NSString * const kCAMediaTimingFunctionEaseInEaseOut
    __OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
CA_EXTERN NSString * const kCAMediaTimingFunctionDefault
    __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_3_0);

具體的效果可以看下面的圖伍纫。kCAMediaTimingFunctionDefault是系統(tǒng)默認(rèn)的時(shí)間函數(shù)。使用這個(gè)函數(shù)來(lái)確保你的動(dòng)畫時(shí)間匹配大多數(shù)系統(tǒng)的動(dòng)畫昂芜。

3.png

你可以對(duì)應(yīng)上圖看下面的效果:


4.gif

你可以點(diǎn)擊這里是獲取CAMediaTimingFunction更多相關(guān)內(nèi)容莹规。你也可以點(diǎn)擊這里自己去操作一下相關(guān)內(nèi)容。

CAAnimationDelegate
每個(gè)動(dòng)畫都有一個(gè)delegate,會(huì)回調(diào)給你一個(gè)動(dòng)畫開(kāi)始和動(dòng)畫結(jié)束的協(xié)議泌神。方便為你的應(yīng)用做相應(yīng)的處理良漱。在動(dòng)畫結(jié)束后你應(yīng)該為layer使用removeAllAnimations移除相應(yīng)的動(dòng)畫,減小不必要的開(kāi)銷欢际。

#pragma  mark - CAAnimationDelegate
- (void)animationDidStart:(CAAnimation *)anim{
    NSLog(@"動(dòng)畫開(kāi)始");
}

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
   
   /*
    因?yàn)槲覀兊膭?dòng)畫repeatCount屬性設(shè)置成了1000母市。所以會(huì)很久才結(jié)束。你可以手動(dòng)修改
    你可以根據(jù)"key值來(lái)判斷是哪個(gè)layer上的動(dòng)畫"
    比如:[XXX.arrowLayer animationForKey:@"positionX"]拿到動(dòng)畫
    */
   NSLog(@"動(dòng)畫結(jié)束");
}

具體相關(guān)的內(nèi)容可以見(jiàn)demo中的CAAnimationViewController

CAPropertyAnimation

CAPropertyAnimationCAAnimation的子類损趋,創(chuàng)造動(dòng)畫的時(shí)候以key-path操作相關(guān)視圖層的屬性來(lái)完成動(dòng)畫患久。
完整的key-path請(qǐng)點(diǎn)擊這里
具體使用key-path操作可以見(jiàn)demo中的CAPropertyAnimationViewController

屬性值
**additive** 決定是否把動(dòng)畫指定的值添加到當(dāng)前render tree 來(lái)產(chǎn)生新的render tree值舶沿。

additive的解釋還是太過(guò)于生硬墙杯,你需要知道layer tree(見(jiàn)最下面的layer tree模塊)。在動(dòng)畫的時(shí)候設(shè)置additive YES后會(huì)把當(dāng)前的presentation layer加入到render tree括荡。

CABasicAnimation

CABasicAnimation對(duì)象為layer提供基本的高镐,單一的frame有關(guān)的動(dòng)畫。CABasicAnimation里面需要注意fromValue畸冲,byValue嫉髓,toValue 屬性控制

設(shè)置預(yù)備的參數(shù):

組合參數(shù)(不為nil) 區(qū)間值
fromValue + toValue [fromValue,toValue]
fromValue + byValue [fromValue,fromValue + byValue]
byValue + toValue [toValue - byValue,toValue]
fromValue [fromValue ,layer當(dāng)前設(shè)置的value]
toValue [layer當(dāng)前設(shè)置的value ,toValue]
byValue [layer當(dāng)前設(shè)置的value ,layer當(dāng)前設(shè)置的value + byValue]
CAKeyframeAnimation

CAKeyframeAnimation對(duì)象有能力為layer對(duì)象提供關(guān)鍵幀動(dòng)畫。你可以通過(guò)指定一個(gè)儲(chǔ)存關(guān)鍵幀的數(shù)組來(lái)控制相應(yīng)的動(dòng)畫時(shí)間和動(dòng)畫行為邑闲。

屬性值
**values**     一個(gè)承載動(dòng)畫多個(gè)關(guān)鍵幀值的數(shù)組
**keyTimes**  一個(gè)承載動(dòng)畫時(shí)間的數(shù)組算行。數(shù)據(jù)的每個(gè)值都在0-1之間,第一個(gè)值為0最后的一個(gè)值為1苫耸。數(shù)組的值對(duì)應(yīng)關(guān)鍵幀數(shù)組的值或者是path路勁的屬性
**path**  一段CGPathRef路徑州邢。layer沿著路勁動(dòng)畫。如果你同時(shí)設(shè)置了values 和path褪子,path路勁將會(huì)被執(zhí)行量淌。path擁有更高的優(yōu)先權(quán)。

具體使用方法可以見(jiàn)demo中的CAKeyframeAnimationViewController嫌褪,雪人是按照path路徑呀枢,社交圖標(biāo)是按照values 效果:

5.gif

CATransaction

對(duì)layer每一次的修改都是事務(wù)的一部分。事物是通過(guò)CATransaction類來(lái)管理的笼痛。CoreAnimation 支持兩種類型的事務(wù):隱式事務(wù)和顯式事務(wù)裙秋。CATransaction類不是通過(guò)alloc init方法來(lái)初始化琅拌。而是借助于begincommit方法。

method:
**begin**  為當(dāng)前線程創(chuàng)建一個(gè)新的事務(wù)
**commit** 提交當(dāng)前的事務(wù)所有的改變項(xiàng)

demoCATransactionViewController類:

- (void)viewDidLoad{
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    
    self.imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"圣誕老人"]];
    self.imageView.frame = CGRectMake(0, 0, 100, 100);
    self.imageView.center = self.view.center;
    [self.view addSubview:self.imageView];
    
    self.redLayer = [CALayer layer];
    self.redLayer.frame = CGRectMake(100, 100, 100, 100);
    self.redLayer.delegate = self;
    self.redLayer.backgroundColor = [UIColor redColor].CGColor;
    [self.view.layer addSublayer:self.redLayer];
    
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//    configure the transaction
    [CATransaction begin];
//    [CATransaction setDisableActions:YES];
    [CATransaction setAnimationDuration:4.0];
    [CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];
    //set the position
    self.redLayer.position  = [[touches anyObject] locationInView:self.view];
    self.imageView.layer.position = [[touches anyObject] locationInView:self.view];
   
    //commit transaction
    [CATransaction commit];
    
    
    NSLog(@"Outside: %@", [self.imageView actionForLayer:self.imageView.layer forKey:@"position"]);
    //begin animation block
    [UIView beginAnimations:nil context:nil];
    //test layer action when inside of animation block
    NSLog(@"Inside: %@", [self.imageView actionForLayer:self.imageView.layer forKey:@"position"]);
    //end animation block
    [UIView commitAnimations];
    
}
6.gif

紅色的視圖是layer.圣誕老人是UIImageView摘刑。當(dāng)點(diǎn)擊了其他區(qū)域进宝,你會(huì)發(fā)現(xiàn)紅色的視圖有一個(gè)緩慢的動(dòng)畫,而圣誕老人馬上就到了指定區(qū)域泣侮。這是因?yàn)?code>UIView的隱式動(dòng)畫被關(guān)聯(lián)圖層給禁用了即彪。
對(duì)于layer圖層你還可以利用下面方法禁用隱式動(dòng)畫。

 [CATransaction setDisableActions:YES];

更多信息你可以點(diǎn)擊這里去了解活尊。也建議讀讀喵大翻譯的View-Layer 協(xié)作.

CAAnimationGroup

CAAnimationGroupCAPropertyAnimation一樣是CAAnimation的子類隶校。CAAnimationGroup可以讓多個(gè)動(dòng)畫組合同時(shí)發(fā)生。

Important
The delegate and removedOnCompletion properties of animations in the [animations
](https://developer.apple.com/reference/quartzcore/caanimationgroup/1412516-animations?language=objc) array are currently ignored. The CAAnimationGroup
 delegate does receive these messages.

layer tree

核心動(dòng)畫中有三種layer tree蛹锰。每一種layer tree在你的應(yīng)用呈現(xiàn)在屏幕中扮演著不同的角色深胳。

  • model layer tree (就是我們應(yīng)用通常使用最多的layer對(duì)象,他們?yōu)閯?dòng)畫儲(chǔ)存著目標(biāo)值。比如:position,paque等)
  • presentation tree(這些layer對(duì)象呈現(xiàn)著一個(gè)動(dòng)畫當(dāng)前值铜犬。比如你的layer沿著x軸歷時(shí)5秒從0到5model layer position會(huì)一直顯示最后的值5舞终,而presentation隨著時(shí)間顯示0,1,2..5。注意你不應(yīng)該人為去修改這些值癣猾。)
  • render tree(這種layer對(duì)象在實(shí)際的動(dòng)畫中,但它對(duì)核心動(dòng)畫來(lái)說(shuō)是私有的敛劝,無(wú)法操作的)
7.png

我們來(lái)驗(yàn)證下,在例子中的LayerTreeViewController類中加入下面的代碼:

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    self.redView.layer.position = CGPointMake(100, 100);
    [self printMethod];
    
    CABasicAnimation *basicAnimation  = [[CABasicAnimation alloc] init];
    basicAnimation.keyPath = @"position.y";
    basicAnimation.fromValue = @0;
    basicAnimation.toValue = @500;
    basicAnimation.duration = 10;
    [self.redView.layer addAnimation:basicAnimation forKey:@"positionY"];
    
 
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0f
                                                      target:self
                                                    selector:@selector(printMethod)
                                                    userInfo:nil
                                                     repeats:YES];
    [timer fire];
    
    
}

- (void)printMethod{
    CALayer *modelLayer = self.redView.layer;
    CALayer *presentationLayer = self.redView.layer.presentationLayer;
    NSLog(@"model layer:%@     presentation layer :%@", NSStringFromCGPoint(modelLayer.position),NSStringFromCGPoint(presentationLayer.position));
}

#pragma mark - get
- (UIView *)redView{
    if (!_redView) {
        _redView = [[UIView alloc] init];
        _redView.frame = CGRectMake(0, 0, 100, 100);
        _redView.backgroundColor = [UIColor redColor];
        _redView.center = self.view.center;
        [self.view addSubview:_redView];
        [self printMethod];
    }
    return _redView;
}

看看打印結(jié)果:

3.png

可以看出presentation layer初始值為(0纷宇,0)夸盟。當(dāng)我們手動(dòng)的去改變postion值,presentation layer沒(méi)有發(fā)現(xiàn)變化而model layer發(fā)生了改變像捶。在使用動(dòng)畫的時(shí)候presentation layer才發(fā)生變化上陕,代表在動(dòng)畫中layer實(shí)時(shí)的值。

更多了解您可以點(diǎn)擊Demo拓春。

參考資料:

官方文檔
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末释簿,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子硼莽,更是在濱河造成了極大的恐慌庶溶,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件懂鸵,死亡現(xiàn)場(chǎng)離奇詭異偏螺,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)矾瑰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門砖茸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)隘擎,“玉大人殴穴,你說(shuō)我怎么就攤上這事。” “怎么了采幌?”我有些...
    開(kāi)封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵劲够,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我休傍,道長(zhǎng)征绎,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任磨取,我火速辦了婚禮人柿,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘忙厌。我一直安慰自己凫岖,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布逢净。 她就那樣靜靜地躺著哥放,像睡著了一般。 火紅的嫁衣襯著肌膚如雪爹土。 梳的紋絲不亂的頭發(fā)上甥雕,一...
    開(kāi)封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音胀茵,去河邊找鬼社露。 笑死,一個(gè)胖子當(dāng)著我的面吹牛宰掉,可吹牛的內(nèi)容都是我干的呵哨。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼轨奄,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼孟害!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起挪拟,我...
    開(kāi)封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤挨务,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后玉组,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體谎柄,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年惯雳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了朝巫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡石景,死狀恐怖劈猿,靈堂內(nèi)的尸體忽然破棺而出拙吉,到底是詐尸還是另有隱情,我是刑警寧澤揪荣,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布筷黔,位于F島的核電站,受9級(jí)特大地震影響仗颈,放射性物質(zhì)發(fā)生泄漏佛舱。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一挨决、第九天 我趴在偏房一處隱蔽的房頂上張望请祖。 院中可真熱鬧,春花似錦脖祈、人聲如沸损拢。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)福压。三九已至,卻和暖如春或舞,著一層夾襖步出監(jiān)牢的瞬間荆姆,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工映凳, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留胆筒,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓诈豌,卻偏偏與公主長(zhǎng)得像仆救,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子矫渔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

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

  • 在iOS中隨處都可以看到絢麗的動(dòng)畫效果彤蔽,實(shí)現(xiàn)這些動(dòng)畫的過(guò)程并不復(fù)雜,今天將帶大家一窺ios動(dòng)畫全貌庙洼。在這里你可以看...
    每天刷兩次牙閱讀 8,465評(píng)論 6 30
  • 在iOS中隨處都可以看到絢麗的動(dòng)畫效果顿痪,實(shí)現(xiàn)這些動(dòng)畫的過(guò)程并不復(fù)雜,今天將帶大家一窺iOS動(dòng)畫全貌油够。在這里你可以看...
    F麥子閱讀 5,096評(píng)論 5 13
  • CAAnimation CAAnimation 是一個(gè)抽像類蚁袭。CAAnimation 也派生出了很多子類,我們使用...
    謝謝生活閱讀 1,352評(píng)論 0 9
  • 一.CoreAnimation介紹 CoreAnimation是一套圖像渲染和動(dòng)畫基礎(chǔ)框架石咬,其在iOS和OSX平臺(tái)...
    AlexCorleone閱讀 968評(píng)論 0 15
  • 繼續(xù)關(guān)于幸福的討論揩悄。討論一個(gè)問(wèn)題,如果缺乏定義鬼悠,推進(jìn)會(huì)很困難的删性。比如棉饶,我問(wèn)你韓國(guó)好不好,你說(shuō)韓國(guó)的泡菜很好镇匀,但是我...
    蔚林閱讀 184評(píng)論 1 1