前言:
Core Animation是一套包含圖形繪制、投影、動畫的Objective-C類集合,該框架包含在QuartzCore.framework
中,它因為被用于處理更為強大的平滑的轉場效果而引入OS X Leopard和iOS而出名。
CPU作為電腦的處理核心,負責處理各種各樣的數(shù)據(jù),什么都可以干。而GPU作為一個專門為圖形高并發(fā)計算
量身定做的處理單元,能同時更新所有的像素
,并把結果顯示到顯示器上,在圖形處理方面具有相當?shù)膶I(yè)性,而且還具有高效的特點。它的出現(xiàn)使得CPU從大量的圖形數(shù)據(jù)處理中解放出來。
上圖中的OpenGL ES是個C語言寫的非常底層的圖形處理框架,是個移動設備上繪制2D和3D計算機圖形的標準開源庫,廣泛地被用在游戲的圖形繪制上,負責直接驅動GPU,效率非常高,缺點是使用起來異常復雜。
Core Animation是對OpenGL ES的Objective-C封裝,具有與OpenGL ES幾乎等價的高性能,卻隱藏了OpenGL ES的復雜性。
我們經(jīng)常說到的硬件加速
其實是指OpenGL
,Core Animation/UIKit基于GPU之上對計算機圖形合成以及繪制的實現(xiàn),直到目前為止,IOS上的硬件加速能力還是大大領先與Android,后者由于依賴CPU的繪制,絕大多數(shù)的動畫實現(xiàn)都會讓人感覺明顯的卡頓。
框架下各類的關系圖:
在介紹框架下各大類之前,首先需要了解一下各大圖層類的父類CALayer,也是CoreAnimation
的基礎,如果有興趣也可以看看CALayer的一些專用圖層子類。
動畫是CoreAnimation
的一個顯著特性,而iOS的動畫也分顯式和隱式的。首先我們來介紹一下隱式動畫:
<一>:隱式動畫
當你改變CALayer的一個可做動畫的屬性,它并不能立刻在屏幕上體現(xiàn)出來。相反,它是從先前的值平滑過渡到新的值。這一切都是默認的行為,你不需要做額外的操作。
之所以叫隱式
是因為我們并沒有指定任何動畫的類型。我們僅僅改變了一個屬性,然后Core Animation來決定如何并且何時去做動畫。
事務(CATransaction):
事務實際上是Core Animation用來包含一系列屬性動畫集合的機制,任何用指定事務去改變可以做動畫的圖層屬性都不會立刻發(fā)生變化,而是當事務一旦提交的時候開始用一個動畫過渡到新值。
Core Animation在每個run loop周期中自動開始一次新的事務(run loop是iOS負責收集用戶輸入,處理定時器或者網(wǎng)絡事件并且重新繪制屏幕的東西),即使你不顯式的用[CATransaction begin]開始一次事務,任何在一次run loop循環(huán)中屬性的改變都會被集中起來,然后做一次 0.25秒 的動畫。
core animation必須在一個transaction里執(zhí)行,在transaction里,layer tree把相應的動畫交給presentation tree去展示。
-
+begin
、commit
:入棧和出棧。 -
+setAnimationDuration:
:設置當前事務的動畫時間。 -
+animationDuration:
獲取當前事務的動畫時間。 -
+setDisableActions:
:可以用來對所有屬性打開或關閉隱式動畫。
http://blog.csdn.net/robincui2011/article/details/9464781
http://www.cnblogs.com/bandy/archive/2012/03/26/2418165.html
隱式動畫和隱式事務:
隱式動畫通過隱式事務實現(xiàn)動畫 。(除顯式事務外,任何對于CALayer屬性的修改,都是隱式事務.這樣的事務會在run-loop中被提交)
layer.backgroundColor = (layer.backgroundColor == redColor) ? blueColor : redColor;
layer.opacity = 1.0f;
layer.position = CGPointMake(layer.position.x +10, layer.position.y);
區(qū)分顯式動畫和顯式事務:
顯式動畫有多種實現(xiàn)方式,顯式事務是一種實現(xiàn)顯式動畫的方式。 ( 通過明確的調用begin,commit來提交動畫 ) .
通過給 CATransaction 類發(fā)送一個 begin 消息來創(chuàng)建一個顯式事務,修改完成之后發(fā)送 comit 消息。顯式事務在同時設置多個圖層的屬性的時候(例如當布局多個圖層的時候),暫時的禁用圖層的行為,或者暫時修改動畫的時間的時候非常有用 .
[CATransaction begin];
[CATransaction setValue:(_swich.on?(id)kCFBooleanTrue:(id)kCFBooleanFalse) forKey:kCATransactionDisableActions];
[self setLayerBC];
[CATransaction commit];
設置動畫是否顯示(禁用圖層行為)(方法控制區(qū)直到函數(shù)的結束):
//默認為YES不顯示
[CATransaction setDisableActions:NO];
暫時禁用圖層行為:
可以在修改圖層屬性值的時候通過設置事務的 kCATransactionDisableActions值為 YES 來暫時禁用圖層的行為。在事務范圍
所作的任何更改也不會因此而發(fā)生的動畫。
[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
[aLayer removeFromSuperlayer];
[CATransaction commit];
重載隱式動畫的時間:
以暫時改變響應改變圖層屬性的動畫的時間,通過設置事務的kCATransactionAnimationDuration 鍵的值為新的時間。事務范圍內所產生的任何動畫都會使用該新設置的時間值而不是他們原有的值。
[CATransaction setValue:[NSNumber numberWithFloat:10.0f]
forKey:kCATransactionAnimationDuration];
簡單使用:(如果對UIView關聯(lián)的圖層做如下動畫是沒有過渡效果的,因為UIView把它關聯(lián)的圖層的可動畫屬性關閉了)
- (IBAction)changeColor
{
[CATransaction begin];
[CATransaction setAnimationDuration:1.0];
CGFloat red = arc4random() / (CGFloat)INT_MAX;
CGFloat green = arc4random() / (CGFloat)INT_MAX;
CGFloat blue = arc4random() / (CGFloat)INT_MAX;
self.colorLayer.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0].CGColor;
//完成塊動畫,類似于UIView的completionBlock
[CATransaction setCompletionBlock:^{
//rotate the layer 90 degrees
CGAffineTransform transform = self.colorLayer.affineTransform;
transform = CGAffineTransformRotate(transform, M_PI_2);
self.colorLayer.affineTransform = transform;
}];
[CATransaction commit];
}
<注>:UIView在+beginAnimations:context:和+commitAnimations之間所有視圖或者圖層屬性的改變而做的動畫都是由于設置了CATransaction的原因。CATransaction的+begin和+commit方法在+animateWithDuration:animations:內部自動調用,可以避免開發(fā)者由于對+begin和+commit匹配的失誤造成的風險。
呈現(xiàn)與模型:
- 呈現(xiàn)圖層:每個圖層屬性的顯示值都被存儲在一個叫做呈現(xiàn)圖層的獨立圖層當中,他可以通過-presentationLayer方法來訪問,可以通過呈現(xiàn)圖層的值來獲取
當前屏幕上真正顯示出來的值
。 - –modelLayer:在呈現(xiàn)圖層上調用–modelLayer將會返回它正在呈現(xiàn)所依賴的CALayer。通常在一個圖層上調用-modelLayer會返回–self
<二>:顯式動畫
能夠對一些屬性做指定的自定義動畫,或者創(chuàng)建非線性動畫,比如沿著任意一條曲線移動。
使用隱式動畫會直接改變layer的屬性值,而使用顯式動畫,動畫結束時不影響動畫前的layer屬性值。
屬性動畫(CAPropertyAnimation)
內部實現(xiàn):
當CALayer的屬性被修改時候,它會調用-actionForKey:(CALayer拿這個結果去對先前和當前的值做動畫。)方法,傳遞屬性的名稱。剩下的操作都在CALayer的頭文件中有詳細的說明,實質上是如下幾步:
檢查是否有委托及委托方法是否實現(xiàn) ==> 檢查包含屬性名稱對應的action字典 ==> 在style字典里搜索屬性名 ==> 調用-defaultActionForKey:方法。
圖層首先檢測它是否有委托,并且是否實現(xiàn)CALayerDelegate協(xié)議指定的-actionForLayer:forKey方法。如果有,直接調用并返回結果。
如果沒有委托,或者委托沒有實現(xiàn)-actionForLayer:forKey方法,圖層接著檢查包含屬性名稱對應行為映射的actions字典。
如果actions字典沒有包含對應的屬性,那么圖層接著在它的style字典接著搜索屬性名。
最后,如果在style里面也找不到對應的行為,那么圖層將會直接調用定義了每個屬性的標準行為的-defaultActionForKey:方法。
當更新屬性的時候,我們需要設置一個新的事務,并且禁用圖層行為
。否則動畫會發(fā)生兩次,一個是因為顯式的CABasicAnimation,另一次是因為隱式動畫
- (void)animationDidStop:(CABasicAnimation *)anim finished:(BOOL)flag
{
[CATransaction begin];
[CATransaction setDisableActions:YES];//禁用隱式動畫的過度效果。
self.colorLayer.backgroundColor = (__bridge CGColorRef)anim.toValue;
[CATransaction commit];
}
-
keyPath
: CAPropertyAnimation 屬性。
基礎動畫(CABasicAnimation):
繼承自CAPropertyAnimation。
參考鏈接
基礎屬性介紹:
防止動畫回到初始狀態(tài)的設置:
我們給一個視圖添加layer動畫時,真正移動并不是我們的視圖本身,而是 presentation layer (呈現(xiàn)圖層) 的一個緩存。動畫開始時 presentation layer開始移動,原始layer(model layer)隱藏,動畫結束時,presentation layer從屏幕上移除,原始layer顯示
transformAnima.removedOnCompletion = NO;
transformAnima.fillMode = kCAFillModeForwards;//將layer的狀態(tài)設置為最終的屬性。
<注>:CABasicAnimation的實例對象只是一個數(shù)據(jù)模型,與綁定到哪一個layer上無關。并且用addAnimation:forKey:
方法時是對CABasicAniamtion對象進行了copy操作的。
避免循環(huán)引用:
CABasicAnimation的代理是強指針引用,在設置代理的時候會造成循環(huán)引用
1、創(chuàng)建一個代理類實現(xiàn)其回調。
self.animation.delegate = [[AnimationDelegate alloc]init];
2、采用虛擬類NSProxy(該類可實現(xiàn)多繼承),可用YYKit
中的YYWeakProxy
類:
self.animation.delegate = [YYWeakProxy proxyWithTarget:self];
區(qū)分不同動畫:
此處不能使用存儲屬性作比較,因為委托傳遞的參數(shù)是對原始值的一個深拷貝,所以兩者并不是一個值。
我們在addAnimation:forKey:
中可設置key值,所以可根據(jù)key值判斷:
1、對比動畫:
[anim isEqual:[self.imageView.layer animationForKey:@"Animation"]]
2、對比key:
[[anim valueForKey:@"AnimationKey"]isEqualToString:@"PositionAnima"]
組動畫 (CAAnimationGroup)
CAAnimationGroup是CAAnimation的子類,可以保存一組動畫對象,將CAAnimationGroup對象加入層后,組中所有動畫對象可以同時并發(fā)運行
-
animations
:用來保存一組動畫對象的NSArray
默認情況下,一組動畫對象是同時運行的,也可以通過設置動畫對象的beginTime屬性來更改動畫的開始時間。
栗子:
CABasicAnimation *positionAnima = [CABasicAnimation animationWithKeyPath:@"position.y"];
positionAnima.fromValue = @(self.imageView.center.y);
positionAnima.toValue = @(self.imageView.center.y-30);
positionAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
CABasicAnimation *transformAnima = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
transformAnima.fromValue = @(0);
transformAnima.toValue = @(M_PI);
transformAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
CAAnimationGroup *animaGroup = [CAAnimationGroup animation];
animaGroup.duration = 2.0f;
animaGroup.fillMode = kCAFillModeForwards;
animaGroup.removedOnCompletion = NO;
animaGroup.animations = @[positionAnima,transformAnima];
[self.imageView.layer addAnimation:animaGroup forKey:@"Animation"];
關鍵幀動畫(CAKeyFrameAnimation):
相比CABasicAnimation的從
fromValue
到toValue
的過渡動畫,CAKeyFrameAnimation可以用一個集合Values
保存關鍵幀值。
-
Values
:指定要用于動畫的關鍵幀值的對象數(shù)組。 -
path
: 基于點的屬性的路徑。 -
keyTimes
:NSNumber對象的可選數(shù)組,用于定義應用給定關鍵幀段的時間,與Values數(shù)組意義對應。范圍:0~1。
關鍵幀動畫:(CAKeyframeAnimation)
-
rotationMode
:設置它為常量kCAAnimationRotateAuto,圖層將會根據(jù)曲線的切線自動旋轉。 -
timingFunctions
:NSArray類型,我們可以用它來對每次動畫的步驟指定不同的計時函數(shù)。但是指定函數(shù)的個數(shù)一定要等于keyframes數(shù)組的元素個數(shù)減一,因為它是描述每一幀之間動畫速度的函數(shù)。
Values方式:
CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
animation.keyPath = @"position";
NSValue *value1=[NSValue valueWithCGPoint:CGPointMake(100, 100)];
NSValue *value2=[NSValue valueWithCGPoint:CGPointMake(200, 100)];
NSValue *value3=[NSValue valueWithCGPoint:CGPointMake(200, 200)];
NSValue *value4=[NSValue valueWithCGPoint:CGPointMake(100, 200)];
NSValue *value5=[NSValue valueWithCGPoint:CGPointMake(100, 100)];
animation.values=@[value1,value2,value3,value4,value5];
animation.repeatCount=MAXFLOAT;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
animation.duration = 4.0f;
animation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation.delegate=self;
//指定時間點。
animation.keyTimes = @[@(0.0),@(0.3),@(0.6),@(0.9),@(1)];
[self.my_View.layer addAnimation:animation forKey:nil];
path方式:
CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
animation.keyPath = @"position";
CGMutablePathRef path=CGPathCreateMutable();
//繪制橢圓 橢圓距離左150,上100,橫向直徑100,豎向直徑300
CGPathAddEllipseInRect(path, NULL, CGRectMake(150, 100, 100, 300));
animation.path=path;
CGPathRelease(path);
animation.repeatCount=MAXFLOAT;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
animation.duration = 4.0f;
animation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation.delegate=self;
[self.my_pathView.layer addAnimation:animation forKey:nil];
過渡動畫(CATransition):
過渡動畫基礎的原則就是對原始的圖層外觀截圖,然后添加一段動畫,平滑過渡到圖層改變之后那個截圖的效果。
CATransition 通常用于通過CALayer控制View子控件的過渡動畫,比如刪除控件,添加控件及切換子控件等。
CATransition有一個type和subtype來標識變換效果,type是一個NSString類型。default:kCATransitionFade。
type
define 定義的常量:
kCATransitionFade 交叉淡化過渡
kCATransitionMoveIn 新視圖移到舊視圖上面
kCATransitionPush 新視圖把舊視圖推出去
kCATransitionReveal 將舊視圖揭開,顯示下面的新視圖
私有方法:
cube 立方體旋轉
suckEffect 收縮動畫
oglFlip 翻轉
rippleEffect 水波動畫
pageCurl 頁面揭開
pageUnCurl 放下頁面
cemeraIrisHollowOpen 鏡頭打開
cameraIrisHollowClose 鏡頭關閉
subtype
用來控制動畫的方向:
kCATransitionFromRight
kCATransitionFromLeft
kCATransitionFromTop
kCATransitionFromBottom
對指定的圖層一次只能使用一次CATransition
,因此,無論你對動畫的鍵設置什么值,過渡動畫都會對它的鍵設置成“transition”,也就是常量kCATransition
。
栗子:
if (self.my_transition==nil) {
self.my_transition=[[UIView alloc]initWithFrame:CGRectMake(0,[UIScreen mainScreen].bounds.size.height-250,[UIScreen mainScreen].bounds.size.width,250)];//這里是動畫最后的位置
self.my_transition.backgroundColor=[UIColor redColor];
[self.view addSubview:self.my_transition];
}
CATransition *animation = [CATransition animation];
animation.duration = 1;
animation.timingFunction = UIViewAnimationCurveEaseInOut;
animation.fillMode = kCAFillModeForwards;
animation.type = kCATransitionMoveIn;//
animation.subtype = kCATransitionFromTop;//向上。
//添加動畫
[self.my_transition.layer addAnimation:animation forKey:nil];
CATransision可以對圖層任何變化平滑過渡的事實使得它成為那些不好做動畫的屬性圖層行為的理想候選,但是對于視圖關聯(lián)的圖層,或者是其他隱式動畫的行為,這個特性依然是被禁用的.
使用UIKit中來做動畫:
- (IBAction)switchImage
{
[UIView transitionWithView:self.imageView duration:1.0
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{
//cycle to next image
UIImage *currentImage = self.imageView.image;
NSUInteger index = [self.images indexOfObject:currentImage];
index = (index + 1) % [self.images count];
self.imageView.image = self.images[index];
}
completion:NULL];
}
在動畫過程中取消動畫:
動畫一旦被移除,圖層的外觀就立刻更新到當前的模型圖層的值。
- 移除指定動畫:
- (void)removeAnimationForKey:(NSString *)key;
- 移除所有動畫:
- (void)removeAllAnimations;
<三>圖層時間
動畫的發(fā)生是需要持續(xù)一段時間的,所以計時對整個概念來說至關重要。
CAMediaTiming協(xié)議:
CAMediaTiming協(xié)議定義了在一段動畫內用來控制逝去時間的屬性的集合,CALayer和CAAnimation都實現(xiàn)了這個協(xié)議,所以時間可以被任意基于一個圖層或者一段動畫的類控制。
duration
和repeatCount
默認都是0。但這不意味著動畫時長為0秒,或者0次,這里的0僅僅代表了“默認”,也就是0.25秒和1次.timeOffset
:timeOffset
只是讓動畫快進到某一點,例如,對于一個持續(xù)1秒的動畫來說,設置timeOffset為0.5意味著動畫將從一半的地方開始。fillMode
:設置當動畫開始或者動畫結束時的值。default:kCAFillModeRemoved
,要把removeOnCompletion
設置為NO。
全局時間:
對
CALayer
或者CAGroupAnimation
調整duration
和repeatCount
/repeatDuration
屬性并不會影響到子動畫。但是beginTime
,timeOffset
和speed
屬性將會影響到子動畫。
馬赫時間:實際上是iOS和Mac OS系統(tǒng)內核的命名,馬赫時間在設備上所有進程都是全局的--但是在不同設備上并不是全局的。當設備休眠的時候馬赫時間會暫停,也就是所有的CAAnimations
(基于馬赫時間)同樣也會暫停。
CFTimeInterval time = CACurrentMediaTime();
本地時間:是根據(jù)父圖層/動畫層級關系中的beginTime
,timeOffset
和speed
屬性計算。就和轉換不同圖層之間坐標關系一樣,CALayer
同樣也提供了方法來轉換不同圖層之間的本地時間。如下:
- (CFTimeInterval)convertTime:(CFTimeInterval)t fromLayer:(CALayer *)l;
- (CFTimeInterval)convertTime:(CFTimeInterval)t toLayer:(CALayer *)l;
暫停、快進和倒回:
給圖層添加一個CAAnimation
實際上是給動畫對象做了一個不可改變的拷貝,所以對原始動畫對象屬性的改變對真實的動畫并沒有作用。相反,直接用-animationForKey:
來檢索圖層正在進行的動畫可以返回正確的動畫對象,但是修改它的屬性將會拋出異常。
一個簡單的方法是可以利用CAMediaTiming
來暫停圖層本身。如果把圖層的speed
設置成0,它會暫停任何添加到圖層上的動畫。類似的,設置speed
大于1.0將會快進,設置成一個負值將會倒回動畫。
通過增加主窗口圖層的speed
,可以暫停整個應用程序的動畫。這對UI自動化提供了好處,我們可以加速所有的視圖動畫來進行自動化測試(注意對于在主窗口之外的視圖并不會被影響,比如UIAlertview
)。可以在app delegate設置如下進行驗證:
self.window.layer.speed = 100;
手動動畫:
timeOffset
一個很有用的功能在于你可以它可以讓你手動控制動畫進程,通過設置speed
為0,可以禁用動畫的自動播放,然后來使用timeOffset
來來回顯示動畫序列。這可以使得運用手勢來手動控制動畫變得很簡單。
緩沖(CAMediaTimingFunction)
動畫速度:
velocity = change / time
對于這種恒定速度的動畫我們稱之為“線性步調”.
CAMediaTimingFunction:
緩沖方程式的使用(同UIView
的options
屬性):
- 顯式:設置
CAAnimation
的timingFunction
為CAMediaTimingFunction
的一個對象。
- 隱式:可以使用
CATransaction
的+setAnimationTimingFunction:
方法。
- 其它:
+timingFunctionWithName:
,傳入以下常量。
kCAMediaTimingFunctionLinear //立即加速并且保持勻速到達終點的場景會有意義
kCAMediaTimingFunctionEaseIn //慢慢加速然后突然停止
kCAMediaTimingFunctionEaseOut //全速開始,然后慢慢減速停止
kCAMediaTimingFunctionEaseInEaseOut //慢慢加速然后再慢慢減速
kCAMediaTimingFunctionDefault //和kCAMediaTimingFunctionEaseInEaseOut很類似,但是加速和減速的過程都稍微有些慢
隱式動畫關于緩沖方程式的使用:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//configure the transaction
[CATransaction begin];
[CATransaction setAnimationDuration:1.0];
[CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];
//set the position
self.colorLayer.position = [[touches anyObject] locationInView:self.view];
//commit transaction
[CATransaction commit];
}
自定義緩沖函數(shù):
CAMediaTimingFunction
的構造函數(shù):+functionWithControlPoints::::
- 通過
CAMediaTimingFunction
中-getControlPointAtIndex:values:
可以用來檢索曲線的點,當知道曲線起始點和終止點,我們便可以通過這個方法將控制點找出來。
Core Animation 的插值機制:
value = (endValue – startValue) × time + startValue;
基于定時器的動畫
定時幀:
NSTimer:iOS上的每個線程都管理了一個NSRunloop
,就是通過一個循環(huán)來完成一些任務列表。
任務包括:
- 處理觸摸事件
- 發(fā)送和接受網(wǎng)絡數(shù)據(jù)包
- 執(zhí)行使用gcd的代碼
- 處理計時器行為
- 屏幕重繪
當你設置一個NSTimer
,他會被插入到當前任務列表中,然后直到指定時間過去之后才會被執(zhí)行。但是何時啟動定時器并沒有一個時間上限,而且它只會在列表中上一個任務完成之后開始執(zhí)行。這通常會導致有幾毫秒的延遲,但是如果上一個任務過了很久才完成就會導致延遲很長一段時間。
優(yōu)化:
- 我們可以用
CADisplayLink
讓更新頻率嚴格控制在每次屏幕刷新之后。 - 基于真實幀的持續(xù)時間而不是假設的更新頻率來做動畫。
- 調整動畫計時器的
run loop
模式,這樣就不會被別的事件干擾。
CADisplayLink:
frameInterval
:整型,指定了間隔了多少幀后才執(zhí)行。(2,表示間隔2幀后執(zhí)行,也就是每秒執(zhí)行60/2 次)。
優(yōu)點: 會保證幀率足夠連續(xù),使得動畫看起來更加平滑。
缺點: 一些失去控制的離散的任務或者事件(例如資源緊張的后臺程序)可能會導致動畫偶爾地丟幀。丟幀后直接忽略,然后下一次更新時繼續(xù)運行。
可以同時對CADisplayLink
指定多個run loop模式,于是我們可以同時加入NSDefaultRunLoopMode
和UITrackingRunLoopMode
來保證它不會被滑動打斷,也不會被其他UIKit控件動畫影響性能,像這樣:
self.timer = [CADisplayLink displayLinkWithTarget:self selector:@selector(step:)];
[self.timer addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
[self.timer addToRunLoop:[NSRunLoop mainRunLoop] forMode:UITrackingRunLoopMode];
全文基于對iOS Core Animation的譯文的理解,接下來我會針對部分細節(jié)功能作更多詳細實例補充,如果喜歡請記得關注我。謝謝您的閱讀~
?