iOS之核心動(dòng)畫(huà)(Core Animation)

CALayer與UIView的關(guān)系

在iOS中,你能看得見(jiàn)摸得著的東西基本上都是UIView娄昆。
在創(chuàng)建UIView對(duì)象時(shí)尤莺,UIView內(nèi)部會(huì)自動(dòng)創(chuàng)建一個(gè)圖層(即CALayer對(duì)象)九串,通過(guò)UIView的layer屬性可以訪問(wèn)這個(gè)層踢步。
當(dāng)UIView需要顯示到屏幕上時(shí)癣亚,會(huì)調(diào)用drawRect:方法進(jìn)行繪圖,并且會(huì)將所有內(nèi)容繪制在自己的圖層上获印,繪圖完畢后述雾,系統(tǒng)會(huì)將圖層拷貝到屏幕上,于是就完成了UIView的顯示兼丰。
換句話說(shuō)玻孟,UIView本身不具備顯示的功能,是它內(nèi)部layer才有顯示功能地粪。

CALayer的基本屬性

    CALayer *layer = [CALayer layer];
   //layer的大小
    layer.bounds = CGRectMake(0, 0, 100, 100);
    layer.backgroundColor = [UIColor redColor].CGColor;
   //位置
    layer.position = CGPointZero;
   //錨點(diǎn)
    layer.anchorPoint = CGPointZero;
   //形變取募,三維的琐谤,uiview是二維
    self.iconView.layer.transform = CATransform3DMakeRotation(M_PI_4, 0, 0, 1);
    [self.view.layer addSublayer:layer];

View和CALayer的Frame,bounds,center 映射

一個(gè) Layer 的 frame 是由它的 anchorPoint,position,bounds,和 transform 共同決定的.

一個(gè) View 的 frame 只是簡(jiǎn)單的返回 Layer的 frame蟆技,View 的 Center 和 Bounds 只是直接返回layer 對(duì)應(yīng)的 Position 和 Bounds。

View中frame getter方法斗忌,bounds和center质礼,UIView并沒(méi)有做什么工作;它只是簡(jiǎn)單的各自調(diào)用它底層的CALayer的frame织阳,bounds和position方法眶蕉。

CALayerd 的 position和anchorPoint的作用

position用來(lái)設(shè)置CALayer在父層中的位置,以父層的左上角為原(0, 0)唧躲。

anchorPoint 稱為“定位點(diǎn)”造挽、“錨點(diǎn)”,決定著CALayer身上的哪個(gè)點(diǎn)會(huì)在position屬性所指的位置弄痹。以自己的左上角為原點(diǎn)(0, 0)饭入,它的x、y取值范圍都是0~1肛真,默認(rèn)值為中心點(diǎn)(0.5, 0.5)谐丢。

    
    CALayer *layer = [CALayer layer];
    layer.bounds = CGRectMake(0, 0, 100, 100);
    layer.backgroundColor = [UIColor redColor].CGColor;
    layer.anchorPoint = CGPointZero;
    layer.position = CGPointMake(0 , 0);
    [self.view.layer addSublayer:layer];

5E16DAF1-D214-4D60-88FE-C22F75375F23.png
    
    CALayer *layer = [CALayer layer];
    layer.bounds = CGRectMake(0, 0, 100, 100);
    layer.backgroundColor = [UIColor redColor].CGColor;
    layer.anchorPoint = CGPointMake(0, 1);
    layer.position = CGPointMake(100 , 100);
    [self.view.layer addSublayer:layer];

EABC3A5D-B349-4ED8-8496-853BF93CAABF.png
  • 綠色箭頭所指的就是錨點(diǎn)和position重合的位置。

Core Animation核心動(dòng)畫(huà)結(jié)構(gòu)圖蚓让。

626233-43bafe84d8aee5bf.png

其中灰色虛線表示繼承關(guān)系乾忱,紅色表示遵守協(xié)議。

核心動(dòng)畫(huà)中所有類都遵守CAMediaTiming協(xié)議历极。
CAAnaimation是個(gè)抽象類窄瘟,不具備動(dòng)畫(huà)效果,必須用它的子類才有動(dòng)畫(huà)效果趟卸。

CAAnimationGroup和CATransition才有動(dòng)畫(huà)效果蹄葱,CAAnimationGroup是個(gè)動(dòng)畫(huà)組纲酗,可以同時(shí)進(jìn)行縮放,旋轉(zhuǎn)(同時(shí)進(jìn)行多個(gè)動(dòng)畫(huà))新蟆。

CATransition是轉(zhuǎn)場(chǎng)動(dòng)畫(huà)觅赊,界面之間跳轉(zhuǎn)(切換)都可以用轉(zhuǎn)場(chǎng)動(dòng)畫(huà)。

CAPropertyAnimation也是個(gè)抽象類琼稻,本身不具備動(dòng)畫(huà)效果吮螺,只有子類才有。

CABasicAnimation和CAKeyframeAnimation:
CABasicAnimation基本動(dòng)畫(huà)帕翻,做一些簡(jiǎn)單效果鸠补。
CAKeyframeAnimation幀動(dòng)畫(huà),做一些連續(xù)的流暢的動(dòng)畫(huà)嘀掸。

CAAnimation 抽象類的一些屬性

CAAnimation是所有動(dòng)畫(huà)對(duì)象的父類紫岩,負(fù)責(zé)控制動(dòng)畫(huà)的持續(xù)時(shí)間和速度,是個(gè)抽象類睬塌,不能直接使用泉蝌,應(yīng)該使用它具體的子類。

3648C83D-A7AB-4461-BB3F-F4AFEDC2E087.png

fillMode屬性的設(shè)置:

  • kCAFillModeRemoved 這個(gè)是默認(rèn)值揩晴,也就是說(shuō)當(dāng)動(dòng)畫(huà)開(kāi)始前和動(dòng)畫(huà)結(jié)束后勋陪,動(dòng)畫(huà)對(duì)layer都沒(méi)有影響,動(dòng)畫(huà)結(jié)束后硫兰,layer會(huì)恢復(fù)到之前的狀態(tài)

  • kCAFillModeForwards 當(dāng)動(dòng)畫(huà)結(jié)束后诅愚,layer會(huì)一直保持著動(dòng)畫(huà)最后的狀態(tài)

  • kCAFillModeBackwards 在動(dòng)畫(huà)開(kāi)始前,只需要將動(dòng)畫(huà)加入了一個(gè)layer劫映,layer便立即進(jìn)入動(dòng)畫(huà)的初始狀態(tài)并等待動(dòng)畫(huà)開(kāi)始违孝。

  • kCAFillModeBoth 這個(gè)其實(shí)就是上面兩個(gè)的合成.動(dòng)畫(huà)加入后開(kāi)始之前,layer便處于動(dòng)畫(huà)初始狀態(tài)泳赋,動(dòng)畫(huà)結(jié)束后layer保持動(dòng)畫(huà)最后的狀態(tài)

速度控制函數(shù)(CAMediaTimingFunction):

kCAMediaTimingFunctionLinear(線性):勻速雌桑,給你一個(gè)相對(duì)靜態(tài)的感覺(jué)

kCAMediaTimingFunctionEaseIn(漸進(jìn)):動(dòng)畫(huà)緩慢進(jìn)入,然后加速離開(kāi)

kCAMediaTimingFunctionEaseOut(漸出):動(dòng)畫(huà)全速進(jìn)入摹蘑,然后減速的到達(dá)目的地

kCAMediaTimingFunctionEaseInEaseOut(漸進(jìn)漸出):動(dòng)畫(huà)緩慢的進(jìn)入筹燕,中間加速,然后減速的到達(dá)目的地衅鹿。這個(gè)是默認(rèn)的動(dòng)畫(huà)行為撒踪。

CAAnimation在分類中定義了代理方法

@protocol CAAnimationDelegate <NSObject>
@optional

/* Called when the animation begins its active duration. */

- (void)animationDidStart:(CAAnimation *)anim;

/* Called when the animation either completes its active duration or
 * is removed from the object it is attached to (i.e. the layer). 'flag'
 * is true if the animation reached the end of its active duration
 * without being removed. */

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;

@end

CAPropertyAnimation

是CAAnimation的子類,也是個(gè)抽象類大渤,要想創(chuàng)建動(dòng)畫(huà)對(duì)象制妄,應(yīng)該使用它的兩個(gè)子類:CABasicAnimation和CAKeyframeAnimation。

屬性keyPath泵三,通過(guò)指定CALayer的一個(gè)屬性名稱為keyPath(NSString類型)耕捞,并且對(duì)CALayer的這個(gè)屬性的值進(jìn)行修改衔掸,達(dá)到相應(yīng)的動(dòng)畫(huà)效果。比如俺抽,指定@“position”為keyPath敞映,就修改CALayer的position屬性的值,以達(dá)到平移的動(dòng)畫(huà)效果,需要注意的是部分屬性值是不支持動(dòng)畫(huà)效果的,以下是具有動(dòng)畫(huà)效果的keyPath:

//CATransform3D Key Paths : (example)transform.rotation.z
     //rotation.x
     //rotation.y
     //rotation.z
     //rotation 旋轉(zhuǎn)

     //scale.x
     //scale.y
     //scale.z
     //scale 縮放

     //translation.x
     //translation.y
     //translation.z
     //translation 平移

     //CGPoint Key Paths : (example)position.x
     //x
     //y

     //CGRect Key Paths : (example)bounds.size.width
     //origin.x
     //origin.y
     //origin
     //size.width
     //size.height
     //size

     //opacity
     //backgroundColor
     //cornerRadius 
     //borderWidth
     //contents 

     //Shadow Key Path:
     //shadowColor 
     //shadowOffset 
     //shadowOpacity 
     //shadowRadius

CABasicAnimation——基本動(dòng)畫(huà)

 // 1.創(chuàng)建動(dòng)畫(huà)對(duì)象
    CABasicAnimation *anim = [CABasicAnimation animation];
    
    // 2.設(shè)置動(dòng)畫(huà)對(duì)象
    // keyPath決定了執(zhí)行怎樣的動(dòng)畫(huà), 調(diào)整哪個(gè)屬性來(lái)執(zhí)行動(dòng)畫(huà)
    anim.keyPath = @"bounds";
    
    anim.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, 200, 200)];
    anim.duration = 2.0;
    
    /**讓圖層保持動(dòng)畫(huà)執(zhí)行完畢后的狀態(tài)**/
    // 動(dòng)畫(huà)執(zhí)行完畢后不要?jiǎng)h除動(dòng)畫(huà)
    anim.removedOnCompletion = NO;
    // 保持最新的狀態(tài)
    anim.fillMode = kCAFillModeForwards;
    
    // 3.添加動(dòng)畫(huà)
    [self.layer addAnimation:anim forKey:@"baseAnimal"];

  • 如果fillMode = kCAFillModeForwards同時(shí)removedOnComletion = NO磷斧,那么在動(dòng)畫(huà)執(zhí)行完畢后振愿,圖層會(huì)保持顯示動(dòng)畫(huà)執(zhí)行后的狀態(tài)。但在實(shí)質(zhì)上弛饭,圖層的屬性值還是動(dòng)畫(huà)執(zhí)行前的初始值冕末,并沒(méi)有真正被改變。

CAKeyframeAnimation——關(guān)鍵幀動(dòng)畫(huà)

關(guān)鍵幀動(dòng)畫(huà)侣颂,也是CAPropertyAnimation的子類档桃,與CABasicAnimation的區(qū)別是:

CABasicAnimation只能從一個(gè)數(shù)值(fromValue)變到另一個(gè)數(shù)值(toValue),而CAKeyframeAnimation會(huì)使用一個(gè)NSArray保存這些數(shù)值
CABasicAnimation可看做是只有2個(gè)關(guān)鍵幀的CAKeyframeAnimation

ED2E1B32-4657-409A-B149-37C1E57D70B4.png
    CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];
    
    anim.keyPath = @"position";
    
    NSValue *v1 = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
    NSValue *v2 = [NSValue valueWithCGPoint:CGPointMake(200, 100)];
    NSValue *v3 = [NSValue valueWithCGPoint:CGPointMake(200, 200)];
    NSValue *v4 = [NSValue valueWithCGPoint:CGPointMake(100, 200)];
    NSValue *v5 = [NSValue valueWithCGPoint:CGPointMake(100, 100)];

    anim.values = @[v1, v2, v3, v4,v5];
    
    anim.duration = 2.1;
    
    
    anim.removedOnCompletion = NO;
    anim.fillMode = kCAFillModeForwards;
    
    [self.redView.layer addAnimation:anim forKey:nil];

    CAKeyframeAnimation * ani = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddEllipseInRect(path, NULL, CGRectMake(130, 200, 100, 100));
    ani.path = path;
    CGPathRelease(path);
    ani.duration = 4.0;
    ani.removedOnCompletion = NO;
    ani.fillMode = kCAFillModeForwards;
    [self.centerShow.layer addAnimation:ani forKey:@"PostionKeyframePathAni"];

CAAnimationGroup——?jiǎng)赢?huà)組

動(dòng)畫(huà)組憔晒,是CAAnimation的子類藻肄,可以保存一組動(dòng)畫(huà)對(duì)象,將CAAnimationGroup對(duì)象加入層后丛晌,組中所有動(dòng)畫(huà)對(duì)象可以同時(shí)并發(fā)運(yùn)行仅炊。

  // 1.創(chuàng)建旋轉(zhuǎn)動(dòng)畫(huà)對(duì)象
    CABasicAnimation *rotate = [CABasicAnimation animation];
    rotate.keyPath = @"transform.rotation";
    rotate.toValue = @(M_PI);
    
    // 2.創(chuàng)建縮放動(dòng)畫(huà)對(duì)象
    CABasicAnimation *scale = [CABasicAnimation animation];
    scale.keyPath = @"transform.scale";
    scale.toValue = @(0.0);
    
    // 3.平移動(dòng)畫(huà)
    CABasicAnimation *move = [CABasicAnimation animation];
    move.keyPath = @"transform.translation";
    move.toValue = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
    
    // 4.將所有的動(dòng)畫(huà)添加到動(dòng)畫(huà)組中
    CAAnimationGroup *group = [CAAnimationGroup animation];
    group.animations = @[rotate, scale, move];
    group.duration = 2.0;
    group.removedOnCompletion = NO;
    group.fillMode = kCAFillModeForwards;
    
    [self.myvie.layer addAnimation:group forKey:nil];

CATransition——轉(zhuǎn)場(chǎng)動(dòng)畫(huà)

CATransition是CAAnimation的子類斗幼,用于做轉(zhuǎn)場(chǎng)動(dòng)畫(huà)澎蛛,能夠?yàn)閷犹峁┮瞥銎聊缓鸵迫肫聊坏膭?dòng)畫(huà)效果。iOS比Mac OS X的轉(zhuǎn)場(chǎng)動(dòng)畫(huà)效果少一點(diǎn)蜕窿。

UINavigationController就是通過(guò)CATransition實(shí)現(xiàn)了將控制器的視圖推入屏幕的動(dòng)畫(huà)效果谋逻。

屬性說(shuō)明:

57AF306E-935F-4EA6-A999-E4C217933AF0.png

過(guò)渡效果設(shè)置

626233-6c72b2e17e35b178.png
  // 轉(zhuǎn)場(chǎng)動(dòng)畫(huà)
    CATransition *anim = [CATransition animation];
//    type的enum值如下:
//    kCATransitionFade 漸變
//    kCATransitionMoveIn 覆蓋
//    kCATransitionPush 推出
//    kCATransitionReveal 揭開(kāi)
    anim.type = @"pageCurl";
    
//    subtype的enum值如下:
//    kCATransitionFromRight 從右邊
//    kCATransitionFromLeft 從左邊
//    kCATransitionFromTop 從頂部
//    kCATransitionFromBottom 從底部
    anim.subtype = kCATransitionFromRight;
    anim.duration = 0.5;
    
//    anim.startProgress = 0.0;
//    
//    anim.endProgress = 0.5;
    
    [self.view.layer addAnimation:anim forKey:nil];

CADisplayLink

CADisplayLink是一種以屏幕刷新頻率觸發(fā)的時(shí)鐘機(jī)制,每秒鐘執(zhí)行大約60次左右桐经。

CADisplayLink是一個(gè)計(jì)時(shí)器毁兆,可以使繪圖代碼與視圖的刷新頻率保持同步,而NSTimer無(wú)法確保計(jì)時(shí)器實(shí)際被觸發(fā)的準(zhǔn)確時(shí)間阴挣。

// 定義
CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(hehe)];
// 添加到主循環(huán)隊(duì)列
[link addToRunLoop:[NSRunLoop mainRunLoop] forMode: NSRunLoopCommonModes];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末气堕,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子畔咧,更是在濱河造成了極大的恐慌茎芭,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,525評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件誓沸,死亡現(xiàn)場(chǎng)離奇詭異梅桩,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)拜隧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)宿百,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)趁仙,“玉大人,你說(shuō)我怎么就攤上這事垦页∪阜眩” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,862評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵痊焊,是天一觀的道長(zhǎng)坐儿。 經(jīng)常有香客問(wèn)我,道長(zhǎng)宋光,這世上最難降的妖魔是什么貌矿? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,728評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮罪佳,結(jié)果婚禮上逛漫,老公的妹妹穿的比我還像新娘。我一直安慰自己赘艳,他們只是感情好酌毡,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著蕾管,像睡著了一般枷踏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上掰曾,一...
    開(kāi)封第一講書(shū)人閱讀 51,590評(píng)論 1 305
  • 那天旭蠕,我揣著相機(jī)與錄音,去河邊找鬼旷坦。 笑死掏熬,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的秒梅。 我是一名探鬼主播旗芬,決...
    沈念sama閱讀 40,330評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼捆蜀!你這毒婦竟也來(lái)了疮丛?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,244評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤辆它,失蹤者是張志新(化名)和其女友劉穎誊薄,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體娩井,經(jīng)...
    沈念sama閱讀 45,693評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡暇屋,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了洞辣。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片咐刨。...
    茶點(diǎn)故事閱讀 40,001評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡昙衅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出定鸟,到底是詐尸還是另有隱情而涉,我是刑警寧澤,帶...
    沈念sama閱讀 35,723評(píng)論 5 346
  • 正文 年R本政府宣布联予,位于F島的核電站啼县,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏沸久。R本人自食惡果不足惜季眷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望卷胯。 院中可真熱鬧子刮,春花似錦、人聲如沸窑睁。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,919評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)担钮。三九已至橱赠,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間箫津,已是汗流浹背狭姨。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,042評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鲤嫡,地道東北人送挑。 一個(gè)月前我還...
    沈念sama閱讀 48,191評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像暖眼,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子纺裁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評(píng)論 2 355

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