一、iOS動(dòng)畫
iOS中實(shí)現(xiàn)一個(gè)動(dòng)畫十分簡(jiǎn)單,在view層面上通過(guò)調(diào)用
[UIView animateWithDuration:duration animations:^{
//執(zhí)行動(dòng)畫
}]
但是它不能控制動(dòng)畫的暫停和組合,所以就需要用到CoreAnimation了。
iOS中的動(dòng)畫主要分為:基礎(chǔ)動(dòng)畫(CABasicAnimation)、關(guān)鍵幀動(dòng)畫(CAKeyFrameAnimation)、動(dòng)畫組(CAAnimationGroup)、轉(zhuǎn)場(chǎng)動(dòng)畫(CATransition),關(guān)系圖如下
- CAAnimation:核心動(dòng)畫的基礎(chǔ)類,不能直接使用,負(fù)責(zé)動(dòng)畫運(yùn)行時(shí)間、速度控制,本身是實(shí)現(xiàn)了CAMediaTiming協(xié)議
- CAPropertyAnimation:屬性動(dòng)畫的基類,即通過(guò)屬性進(jìn)行動(dòng)畫設(shè)置,不能直接使用。
- CAAnimationGroup:動(dòng)畫組,可以通過(guò)動(dòng)畫組來(lái)進(jìn)行所有動(dòng)畫行為的統(tǒng)一控制,組中所有動(dòng)畫可以并發(fā)執(zhí)行。
- CATransition:轉(zhuǎn)場(chǎng)動(dòng)畫,主要通過(guò)濾鏡進(jìn)行動(dòng)畫效果設(shè)置。
- CABasicAnimation:基礎(chǔ)動(dòng)畫,通過(guò)修改屬性進(jìn)行動(dòng)畫參數(shù)控制,只有初始狀態(tài)和結(jié)束狀態(tài)。
- CAKeyFrameAnimation:關(guān)鍵幀懂的規(guī)劃,通過(guò)修改屬性進(jìn)行動(dòng)畫,可以有多個(gè)狀態(tài)控制。
二、簡(jiǎn)單動(dòng)畫的實(shí)現(xiàn)(CABasicAnimation)
You can perform simple animations implicitly or explicitly depending on your needs. Implicit animations use the default timing and animation properties to perform an animation, whereas explicit animations require you to configure those properties yourself using an animation object. So implicit animations are perfect for situations where you want to make a change without a lot of code and the default timing works well for you.
apple提供隱式動(dòng)畫和顯式動(dòng)畫兩種,隱式動(dòng)畫使用系統(tǒng)默認(rèn)的時(shí)間和屬性,如果要顯式動(dòng)畫,需要用戶自己配置屬性。當(dāng)用戶想要用少量代碼和默認(rèn)的時(shí)間實(shí)現(xiàn)簡(jiǎn)單的動(dòng)畫,用隱式就行了。
什么是隱式動(dòng)畫,顯式動(dòng)畫?
- 隱式動(dòng)畫就是不需要手動(dòng)調(diào)用動(dòng)畫方法,系統(tǒng)默認(rèn)提供的動(dòng)畫效果,時(shí)間是1/4秒,root layer沒(méi)有隱式動(dòng)畫。當(dāng)你改變了layer的屬性,apple會(huì)立刻把這個(gè)屬性改變,但是會(huì)通過(guò)呈現(xiàn)樹以動(dòng)畫的形式展示改變的效果(這也就是為什么apple建議通過(guò)presentationLayer的屬性來(lái)訪問(wèn)當(dāng)前屏幕上的layer信息了),這個(gè)動(dòng)態(tài)改變的過(guò)程就是隱式動(dòng)畫。
- 顯式動(dòng)畫是開發(fā)者自定義的動(dòng)畫效果,可以設(shè)置屬性改變的時(shí)間長(zhǎng)度,改變的效果(淡入淡出等)。
2.1 單個(gè)動(dòng)畫
實(shí)現(xiàn)簡(jiǎn)單動(dòng)畫通常都用CABasicAnimation
對(duì)象和用戶配置好的動(dòng)畫參數(shù)來(lái)實(shí)現(xiàn),通過(guò)調(diào)用basicAni的addAnimation:forKey:
方法將動(dòng)畫添加到layer里面,這個(gè)方法會(huì)根據(jù)填入的key值來(lái)決定讓哪個(gè)屬性進(jìn)行動(dòng)畫。
圖層動(dòng)畫的本質(zhì)就是將圖層內(nèi)部的內(nèi)容轉(zhuǎn)化為位圖經(jīng)硬件操作形成一種動(dòng)畫效果,其實(shí)圖層本身并沒(méi)有任何的變化
也就是說(shuō)動(dòng)畫不會(huì)從根本上改變layer的屬性,只是展示屬性變化的效果
簡(jiǎn)單動(dòng)畫會(huì)在一定時(shí)間內(nèi)通過(guò)動(dòng)畫的形式改變layer的屬性值,比如用動(dòng)畫效果將透明度opacity從1到0:
以透明度為例實(shí)現(xiàn)簡(jiǎn)單動(dòng)畫:
CABasicAnimation *fade = [CABasicAnimation animationWithKeyPath:@"opacity"];
fade.fromValue = [NSNumber numberWithFloat:1.0];
fade.toValue = [NSNumber NumberWithFloat:0.0];
fade.duration = 1.0;
//注意key相當(dāng)于給動(dòng)畫進(jìn)行命名,以后獲得該動(dòng)畫時(shí)可以使用此名稱獲取
[self.layer addAnimation:fade forKey:@"opacity];
//動(dòng)畫不會(huì)真正改變opacity的值,在動(dòng)畫結(jié)束后要手動(dòng)更改
self.opacity = 0;
還可以通過(guò)animation 的delegate方法監(jiān)測(cè)動(dòng)畫是否執(zhí)行完畢
CABasicAnimation *fade = [CABasicAnimation animationWithKeyPath:@"opacity"];
fade.fromValue = [NSNumber numberWithFloat:1.0];
fade.toValue = [NSNumber NumberWithFloat:0.0];
fade.duration = 1.0;
fade.delegate = self;
//注意key相當(dāng)于給動(dòng)畫進(jìn)行命名,以后獲得該動(dòng)畫時(shí)可以使用此名稱獲取
[self.layer addAnimation:fade forKey:@"opacity];
//動(dòng)畫不會(huì)真正改變opacity的值,在動(dòng)畫結(jié)束后要手動(dòng)更改
//代理方法
- (void)animationDidStart:(CAAnimation *)anim{
NSLog(@"START");
}
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
//如果不通過(guò)動(dòng)畫事務(wù)將隱式動(dòng)畫關(guān)閉,會(huì)出現(xiàn)動(dòng)畫運(yùn)行完畢后會(huì)從起點(diǎn)突變到終點(diǎn)。
[CATransaction begin];
[CATransaction setDisableActions:YES];
self.layer.position = [[anim valueForKey:@"KPOINT"] CGPointValue];
[CATransaction commit];
}
Tip: When creating an explicit animation, it is recommended that you always assign a value to the fromValue property of the animation object. If you do not specify a value for this property, Core animation uses the layer’s current value as the starting value. If you already updated the property to its final value, that might not yield the results you want.
顯式動(dòng)畫,apple建議你總是給fromValue
賦值,如果你不賦值給fromValue
,系統(tǒng)會(huì)取當(dāng)前的屬性值作為起始點(diǎn),如果你更新了最終值,可能會(huì)得到意向不到的結(jié)果(不是很明白它的意思,我的理解是如果沒(méi)更改最終值,這個(gè)屬性是不會(huì)被動(dòng)畫改變的,動(dòng)畫只是視覺(jué)上的效果,原因見下)。
Unlike an implicit animation, which updates the layer object’s data value, an explicit animation does not modify the data in the layer tree. Explicit animations only produce the animations. At the end of the animation, Core Animation removes the animation object from the layer and redraws the layer using its current data values.
隱式動(dòng)畫會(huì)直接改變?cè)搶傩缘闹?,而顯式動(dòng)畫只是一個(gè)動(dòng)畫效果,Core Animation會(huì)根據(jù)屬性的最終值重回layer,所有必須在動(dòng)畫結(jié)束之后手動(dòng)更改屬性值,除非你不想改變?cè)搶傩浴?/p>
2.2 多個(gè)動(dòng)畫組合
實(shí)現(xiàn)移動(dòng)過(guò)程中旋轉(zhuǎn)的動(dòng)畫效果:
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
CGPoint p = [[touches anyObject] locationInView:self.view];
CALayer *layer = self.leftBottomView.layer;
self.layer = layer;
//添加動(dòng)畫
[self positionLayer:layer position:p];
[self rotate:layer];
}
-(void)rotate:(CALayer *)layer{
CABasicAnimation *basicAnimation=[CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
basicAnimation.toValue=[NSNumber numberWithFloat:M_PI_2*3];
basicAnimation.duration=3.0;
//添加動(dòng)畫到圖層,注意key相當(dāng)于給動(dòng)畫進(jìn)行命名,以后獲得該動(dòng)畫時(shí)可以使用此名稱獲取
[layer addAnimation:basicAnimation forKey:@"KCBasicAnimation_Rotation"];
}
-(void)positionLayer:(CALayer *)layer position:(CGPoint)p{
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
animation.toValue = [NSValue valueWithCGPoint:p];
animation.duration = 3;
animation.delegate = self;
[animation setValue:[NSValue valueWithCGPoint:p] forKey:@"KPOINT"];
[layer addAnimation:animation forKey:@"KPOSITION"];
}
- (void)animationDidStart:(CAAnimation *)anim{
NSLog(@"START");
[self.layer animationForKey:@"KPOSITION"];
}
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
[CATransaction begin];
[CATransaction setDisableActions:YES];
self.layer.position = [[anim valueForKey:@"KPOINT"] CGPointValue];
[CATransaction commit];
}
三、關(guān)鍵幀動(dòng)畫(CAKeyFramedAnimation)
3.1 關(guān)鍵幀動(dòng)畫簡(jiǎn)單實(shí)現(xiàn)
CABasicAnimation只能設(shè)定初始和最終值,動(dòng)畫也只能是簡(jiǎn)單的從一個(gè)值到另一個(gè)值的變化。CAKeyFramedAnimation能夠通過(guò)改變多個(gè)值,讓你們的動(dòng)畫能夠以線性或者非線性的方式展現(xiàn)??梢园裬eyFramedAnimation看成是許多個(gè)basicAnimation組合而成,每?jī)蓚€(gè)變化值之間的動(dòng)畫看成一個(gè)簡(jiǎn)單動(dòng)畫。
以改變layer的position為例通過(guò)設(shè)置關(guān)鍵幀,做出曲線動(dòng)畫,它會(huì)根據(jù)設(shè)定的path
值
,通過(guò)描繪路徑進(jìn)行關(guān)鍵幀動(dòng)畫控制:
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
CGPoint p = [[touches anyObject] locationInView:self.view];
CALayer *layer = self.leftBottomView.layer;
self.layer = layer;
//開始動(dòng)畫
[self keyFramed:layer];
//動(dòng)畫結(jié)束之后改變layer位置
layer.position = CGPointMake(layer.position.x, layer.position.y+200);
}
-(void)keyFramed:(CALayer *)layer{
CAKeyframeAnimation *keyFramedAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
//創(chuàng)建路徑
CGMutablePathRef path = CGPathCreateMutable();
CGFloat x = layer.position.x;
CGFloat y = layer.position.y;
//添加貝塞爾曲線路徑
CGPathMoveToPoint(path, nil, x, y);
CGPathAddCurveToPoint(path, nil, x+200, y, x+200, y+100, x, y+100);
CGPathAddCurveToPoint(path, nil, x+200, y+100, x+200, y+200, x, y+200);
keyFramedAnimation.path = path;
keyFramedAnimation.duration = 5;
[layer addAnimation:keyFramedAnimation forKey:@"KEYFRAME"];
}
3.2 其他屬性解析
- calculationMode:
The calculationMode property defines the algorithm to use in calculating the animation timing. The value of this property affects how the other timing-related properties are used
calculationMode
,動(dòng)畫計(jì)算模式,規(guī)定了動(dòng)畫時(shí)間的算法,對(duì)與時(shí)間有關(guān)的動(dòng)畫屬性起作用。它是一個(gè)字符串類型,有如下:
//線性動(dòng)畫,是計(jì)算模式的默認(rèn)值
kCAAnimationLinear
//離散動(dòng)畫,每幀之間沒(méi)有過(guò)渡
kCAAnimationDiscrete
//均勻動(dòng)畫,會(huì)忽略keyTimes
kCAAnimationPaced
//平滑執(zhí)行
kCAAnimationCubic
//平滑均勻執(zhí)行
kCAAnimationCubicPaced
各個(gè)值的動(dòng)畫效果示意圖:
- keyTimes:
The keyTimes property specifies time markers at which to apply each keyframe value
keyTimes
用于設(shè)置每幀之間的動(dòng)畫執(zhí)行時(shí)間,但是只有在calculationMode
為KCAAnimationLinear
、KCAAnimationDiscrete
、KCAAnimationCubic
的時(shí)候才有效。
改變keyTimes來(lái)改變每幀的動(dòng)畫時(shí)間:
CAKeyframeAnimation *keyFramedAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
CGMutablePathRef path = CGPathCreateMutable();
CGFloat x = layer.position.x;
CGFloat y = layer.position.y;
CGPathMoveToPoint(path, nil, x, y);
CGPathAddCurveToPoint(path, nil, x+200, y, x+200, y+100, x, y+100);
CGPathAddCurveToPoint(path, nil, x+200, y+100, x+200, y+200, x, y+200);
keyFramedAnimation.path = path;
keyFramedAnimation.duration = 5;
keyFramedAnimation.calculationMode = kCAAnimationCubicPaced;
keyFramedAnimation.keyTimes = @[@0.0,@0.2,@1.0];
[layer addAnimation:keyFramedAnimation forKey:@"KEYFRAME"];
四、動(dòng)畫組
CABasicAnimation和CAKeyFramedAnimatio一次只能改變一個(gè)屬性,顯示開發(fā)中要實(shí)現(xiàn)的動(dòng)畫效果一般都是多個(gè)動(dòng)畫一起執(zhí)行的,比如平移過(guò)程中加入旋轉(zhuǎn)效果等等。通過(guò)CAAnimationGroup能讓開發(fā)者自由組合多個(gè)動(dòng)畫效果。
動(dòng)畫組的實(shí)現(xiàn)并不復(fù)雜,只需要將各個(gè)動(dòng)畫創(chuàng)建好再添加到動(dòng)畫組內(nèi)就行了。
來(lái)給上面的關(guān)鍵幀動(dòng)畫加上旋轉(zhuǎn)效果試試:
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
CGPoint p = [[touches anyObject] locationInView:self.view];
CALayer *layer = self.leftBottomView.layer;
CAAnimationGroup *group = [CAAnimationGroup animation];
CAKeyframeAnimation *key = [self createKeyFramed:layer];
CABasicAnimation *rotate = [self createRotate:layer];
group.animations = @[key,rotate];
[layer addAnimation:group forKey:@"GROUP"];
layer.position = CGPointMake(layer.position.x, layer.position.y+200);
}
-(CAKeyframeAnimation *)createKeyFramed:(CALayer *)layer{
CGFloat x = layer.position.x;
CGFloat y = layer.position.y;
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, nil, x, y);
CGPathAddCurveToPoint(path, nil, x+200, y, x+200, y+100, x, y+100);
CGPathAddCurveToPoint(path, nil, x+200, y+100, x+200, y+200, x, y+200);
CAKeyframeAnimation *keyFramedAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
keyFramedAnimation.path = path;
keyFramedAnimation.duration = 5;
[layer addAnimation:keyFramedAnimation forKey:@"KEYFRAME"];
return keyFramedAnimation;
}
-(CABasicAnimation *)createRotate:(CALayer *)layer{
CABasicAnimation *rotate=[CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
rotate.toValue =[NSNumber numberWithFloat:M_PI_2*3];
rotate.duration =5.0;
[layer addAnimation:rotate forKey:@"KCBasicAnimation_Rotation"];
return rotate;
}
官方文檔給的示例代碼:
// Animation 1
CAKeyframeAnimation* widthAnim = [CAKeyframeAnimation animationWithKeyPath:@"borderWidth"];
NSArray* widthValues = [NSArray arrayWithObjects:@1.0, @10.0, @5.0, @30.0, @0.5, @15.0, @2.0, @50.0, @0.0, nil];
widthAnim.values = widthValues;
widthAnim.calculationMode = kCAAnimationPaced;
// Animation 2
CAKeyframeAnimation* colorAnim = [CAKeyframeAnimation animationWithKeyPath:@"borderColor"];
NSArray* colorValues = [NSArray arrayWithObjects:(id)[UIColor greenColor].CGColor,
(id)[UIColor redColor].CGColor, (id)[UIColor blueColor].CGColor, nil];
colorAnim.values = colorValues;
colorAnim.calculationMode = kCAAnimationPaced;
// Animation group
CAAnimationGroup* group = [CAAnimationGroup animation];
group.animations = [NSArray arrayWithObjects:colorAnim, widthAnim, nil];
group.duration = 5.0;
[myLayer addAnimation:group forKey:@"BorderChanges"];
五、轉(zhuǎn)場(chǎng)動(dòng)畫(CATransition)
轉(zhuǎn)場(chǎng)動(dòng)畫會(huì)為layer的轉(zhuǎn)換添加一個(gè)視覺(jué)效果,最常見的是一個(gè)layer的消失和另一個(gè)layer的出現(xiàn)。
子類型:
CATransition* transition = [CATransition animation];
transition.startProgress = 0;
transition.endProgress = 1.0;
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromRight;
transition.duration = 1.0;
// Add the transition animation to both layers
[myView1.layer addAnimation:transition forKey:@"transition"];
[myView2.layer addAnimation:transition forKey:@"transition"];
// Finally, change the visibility of the layers.
myView1.hidden = YES;
myView2.hidden = NO;
六、暫停和繼續(xù)動(dòng)畫
在iOS動(dòng)畫時(shí)間是動(dòng)畫十分重要的一部分,Core Animation 通過(guò)調(diào)用 CAMediaTiming
協(xié)議的屬性和方法來(lái)精確的設(shè)定時(shí)間信息。
However, the local time of a layer can be modified by its parent layers or by its own timing parameters. For example, changing the layer’s speed property causes the duration of animations on that layer (and its sublayers) to change proportionally
每個(gè)動(dòng)畫都有自己的local time,用來(lái)管理動(dòng)畫時(shí)間信息。通常兩個(gè)layer的local time是十分接近的,因此開發(fā)者不必去關(guān)心這方面的事情,但是改變了layer的speed
屬性的話就會(huì)導(dǎo)致動(dòng)畫的時(shí)間周期改變,從而影響各個(gè)layer動(dòng)畫local time。
beginTime指定了動(dòng)畫開始之前的的延遲時(shí)間。這里的延遲從動(dòng)畫添加到可見圖層的那一刻開始測(cè)量,默認(rèn)是0(就是說(shuō)動(dòng)畫會(huì)立刻執(zhí)行)。
speed是一個(gè)時(shí)間的倍數(shù),默認(rèn)1.0,減少它會(huì)減慢圖層/動(dòng)畫的時(shí)間,增加它會(huì)加快速度。如果2.0的速度,那么對(duì)于一個(gè)duration為1的動(dòng)畫,實(shí)際上在0.5秒的時(shí)候就已經(jīng)完成了。
timeOffset和beginTime類似,但是和增加beginTime導(dǎo)致的延遲動(dòng)畫不同,增加timeOffset只是讓動(dòng)畫快進(jìn)到某一點(diǎn),例如,對(duì)于一個(gè)持續(xù)1秒的動(dòng)畫來(lái)說(shuō),設(shè)置timeOffset為0.5意味著動(dòng)畫將從一半的地方開始。
和beginTime不同的是,timeOffset并不受speed的影響。所以如果你把speed設(shè)為2.0,把timeOffset設(shè)置為0.5,那么你的動(dòng)畫將從動(dòng)畫最后結(jié)束的地方開始,因?yàn)?秒的動(dòng)畫實(shí)際上被縮短到了0.5秒。然而即使使用了timeOffset讓動(dòng)畫從結(jié)束的地方開始,它仍然播放了一個(gè)完整的時(shí)長(zhǎng),這個(gè)動(dòng)畫僅僅是循環(huán)了一圈,然后從頭開始播放。
Core Animation的 馬赫時(shí)間 ,可以使用CACurrentMediaTime
來(lái)訪問(wèn),它返回了設(shè)備自從上次啟動(dòng)到現(xiàn)在的時(shí)間(然而這并沒(méi)什么卵用),它的真實(shí)作用在于對(duì)動(dòng)畫的時(shí)間測(cè)量提供了一個(gè)相對(duì)值。
每個(gè)CALayer和CoreAnimation都有自己的本地時(shí)間概念,系統(tǒng)提供了兩個(gè)方法:
-(CFTimeInterval)convertTime:(CGTimeInterval)t fromLayer:(CALayer *)l;
-(CFTimeInterval)convertTime:(CGTimeInterval)t toLayer:(CALayer *)l;
配合父圖層/動(dòng)畫圖層關(guān)系中的beginTime
,timeOff
,speed
,可以控制動(dòng)畫的暫停,快退/快進(jìn)的功能:
用一個(gè)小demo實(shí)現(xiàn)暫停、繼續(xù)動(dòng)畫功能:
- (void)pauseAnimation:(CALayer *)layer{
CFTimeInterval pauseTime = [self.layer convertTime:CACurrentMediaTime() fromLayer:nil];
layer.timeOffset = pauseTime;
layer.speed = 0;
}
- (void)resumeAnimation:(CALayer *)layer{
CFTimeInterval pauseTime = [self.layer timeOffset];
layer.timeOffset = 0;
layer.beginTime = 0;
layer.speed = 1;
CFTimeInterval timeSincePause = [self.layer convertTime:CACurrentMediaTime() fromLayer:nil] - pauseTime;
layer.beginTime = timeSincePause;
}
- (IBAction)pause:(id)sender {
self.stop = !self.stop;
if (self.stop) {
[self animationResume];
}else{
[self animationPause];
}
}
得到的效果
七、動(dòng)畫事務(wù)(CATransaction)
CATransaction負(fù)責(zé)管理動(dòng)畫、動(dòng)畫組的創(chuàng)建和執(zhí)行。大部分情況下開發(fā)者不需要手動(dòng)創(chuàng)建trasaction(動(dòng)畫事務(wù)),但如果要更精確的控制動(dòng)畫的屬性,比如duration
,timing function等,就要通過(guò)手動(dòng)創(chuàng)建CATrasaction。
開啟新的動(dòng)畫事務(wù)調(diào)用start
方法,結(jié)束事務(wù)調(diào)用commit
方法。
apple給的簡(jiǎn)單示例代碼,通過(guò):
[CATransaction begin];
theLayer.zPosition=200.0;
theLayer.opacity=0.0;
[CATransaction commit];
CATransaction通過(guò)block運(yùn)行開發(fā)者在動(dòng)畫在動(dòng)畫結(jié)束之后執(zhí)行一些其他操作:
[CATransaction setCompletionBlock:^{
//執(zhí)行動(dòng)畫結(jié)束之后的操作
}];
CATransaction通過(guò)setValue:forKey
來(lái)改變動(dòng)畫的屬性,key值是使用的是系統(tǒng)提供的字符串類型值,以改變動(dòng)畫時(shí)間為例:
[CATransaction begin];
[CATransaction setValue:@10 forKey:kCATransactionAnimationDuration];
[CATransaction comment];
除了時(shí)間外還有:
kCATransactionDisableActions
kCATransactionAnimationTimingFunction
kCATransactionCompletionBlock
CATransaction允許一個(gè)事務(wù)內(nèi)嵌套多個(gè)事務(wù)的操作,但是每個(gè)動(dòng)畫事務(wù)的begin
和commit
必須配套使用。
//outer transaction
[CATransaction begin];
CATransaction setValue:@2 forKey:kCATransactionAnimationDuration];
layer.positon = CGPointMake(0,0);
//inner transaction
[CATransaction begin];
[CATranscation setValue:@3 forKey:kCATransactionAnimationDuration];
layer.zPosition = 200;
layer.opacity = 0;
//inner transaction completed
[CATransaction commit];
//outer transaction completed
[CATranscation commit]