iOS動(dòng)畫-通過CALayer讓你的愛啪啪(APP)動(dòng)起來

一葫掉、iOS動(dòng)畫

iOS中實(shí)現(xiàn)一個(gè)動(dòng)畫十分簡(jiǎn)單,在view層面上通過調(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)系圖如下

動(dòng)畫關(guān)系圖
  • CAAnimation:核心動(dòng)畫的基礎(chǔ)類哟沫,不能直接使用,負(fù)責(zé)動(dòng)畫運(yùn)行時(shí)間锌介、速度控制嗜诀,本身是實(shí)現(xiàn)了CAMediaTiming協(xié)議
  • CAPropertyAnimation:屬性動(dòng)畫的基類,即通過屬性進(jìn)行動(dòng)畫設(shè)置孔祸,不能直接使用隆敢。
  • CAAnimationGroup:動(dòng)畫組,可以通過動(dòng)畫組來進(jìn)行所有動(dòng)畫行為的統(tǒng)一控制崔慧,組中所有動(dòng)畫可以并發(fā)執(zhí)行拂蝎。
  • CATransition:轉(zhuǎn)場(chǎng)動(dòng)畫,主要通過濾鏡進(jìn)行動(dòng)畫效果設(shè)置惶室。
  • CABasicAnimation:基礎(chǔ)動(dòng)畫温自,通過修改屬性進(jìn)行動(dòng)畫參數(shù)控制,只有初始狀態(tài)和結(jié)束狀態(tài)皇钞。
  • CAKeyFrameAnimation:關(guān)鍵幀懂的規(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沒有隱式動(dòng)畫键俱。當(dāng)你改變了layer的屬性兰绣,apple會(huì)立刻把這個(gè)屬性改變,但是會(huì)通過呈現(xiàn)樹以動(dòng)畫的形式展示改變的效果(這也就是為什么apple建議通過presentationLayer的屬性來訪問當(dāng)前屏幕上的layer信息了)编振,這個(gè)動(dòng)態(tài)改變的過程就是隱式動(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ù)來實(shí)現(xiàn),通過調(diào)用basicAni的addAnimation:forKey:方法將動(dòng)畫添加到layer里面,這個(gè)方法會(huì)根據(jù)填入的key值來決定讓哪個(gè)屬性進(jìn)行動(dòng)畫畅蹂。

圖層動(dòng)畫的本質(zhì)就是將圖層內(nèi)部的內(nèi)容轉(zhuǎn)化為位圖經(jīng)硬件操作形成一種動(dòng)畫效果健无,其實(shí)圖層本身并沒有任何的變化
也就是說動(dòng)畫不會(huì)從根本上改變layer的屬性,只是展示屬性變化的效果

簡(jiǎn)單動(dòng)畫會(huì)在一定時(shí)間內(nèi)通過動(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;

還可以通過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{
    //如果不通過動(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é)果(不是很明白它的意思,我的理解是如果沒更改最終值脆贵,這個(gè)屬性是不會(huì)被動(dòng)畫改變的风响,動(dòng)畫只是視覺上的效果,原因見下)丹禀。

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)過程中旋轉(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];
}
多個(gè)動(dòng)畫結(jié)合

三、關(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能夠通過改變多個(gè)值贫导,讓你們的動(dòng)畫能夠以線性或者非線性的方式展現(xiàn)◇№铮可以把keyFramedAnimation看成是許多個(gè)basicAnimation組合而成孩灯,每?jī)蓚€(gè)變化值之間的動(dòng)畫看成一個(gè)簡(jiǎn)單動(dòng)畫。

以改變layer的position為例通過設(shè)置關(guān)鍵幀逾滥,做出曲線動(dòng)畫峰档,它會(huì)根據(jù)設(shè)定的path
![Uploading keyframe_717706.gif . . .](pathCGPathRef類型),通過描繪路徑進(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"];
}
keyFrameAnimation

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)畫捉蚤,每幀之間沒有過渡
kCAAnimationDiscrete
//均勻動(dòng)畫抬驴,會(huì)忽略keyTimes
kCAAnimationPaced
//平滑執(zhí)行
kCAAnimationCubic
//平滑均勻執(zhí)行
kCAAnimationCubicPaced

各個(gè)值的動(dòng)畫效果示意圖:

calculationMode示意圖
  • keyTimes:

The keyTimes property specifies time markers at which to apply each keyframe value

keyTimes用于設(shè)置每幀之間的動(dòng)畫執(zhí)行時(shí)間,但是只有在calculationModeKCAAnimationLinear 外里、KCAAnimationDiscrete怎爵、KCAAnimationCubic的時(shí)候才有效。

改變keyTimes來改變每幀的動(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"];
keytime

四盅蝗、動(dòng)畫組

CABasicAnimation和CAKeyFramedAnimatio一次只能改變一個(gè)屬性鳖链,顯示開發(fā)中要實(shí)現(xiàn)的動(dòng)畫效果一般都是多個(gè)動(dòng)畫一起執(zhí)行的,比如平移過程中加入旋轉(zhuǎn)效果等等墩莫。通過CAAnimationGroup能讓開發(fā)者自由組合多個(gè)動(dòng)畫效果芙委。

動(dòng)畫組的實(shí)現(xiàn)并不復(fù)雜,只需要將各個(gè)動(dòng)畫創(chuàng)建好再添加到動(dòng)畫組內(nè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;
}
GROUP

官方文檔給的示例代碼:

// 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è)視覺效果,最常見的是一個(gè)layer的消失和另一個(gè)layer的出現(xiàn)裂问。

4196_141022104125_1.jpg

子類型:

4196_141022104212_1.jpg
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 通過調(diào)用 CAMediaTiming協(xié)議的屬性和方法來精確的設(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痊乾,用來管理動(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(就是說動(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)畫來說,設(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來訪問纠拔,它返回了設(shè)備自從上次啟動(dòng)到現(xiàn)在的時(shí)間(然而這并沒什么卵用)秉剑,它的真實(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];
    }
}

得到的效果


pause

七、動(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等,就要通過手動(dòng)創(chuàng)建CATrasaction既鞠。

開啟新的動(dòng)畫事務(wù)調(diào)用start方法煤傍,結(jié)束事務(wù)調(diào)用commit方法。

apple給的簡(jiǎn)單示例代碼,通過:

[CATransaction begin];
theLayer.zPosition=200.0;
theLayer.opacity=0.0;
[CATransaction commit];

CATransaction通過block運(yùn)行開發(fā)者在動(dòng)畫在動(dòng)畫結(jié)束之后執(zhí)行一些其他操作:

[CATransaction setCompletionBlock:^{
          //執(zhí)行動(dòng)畫結(jié)束之后的操作
    }];

CATransaction通過setValue:forKey來改變動(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ù)的begincommit必須配套使用。

//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]

閱讀原文

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末洒敏,一起剝皮案震驚了整個(gè)濱河市龄恋,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌凶伙,老刑警劉巖郭毕,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異函荣,居然都是意外死亡显押,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門傻挂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來乘碑,“玉大人,你說我怎么就攤上這事金拒∈薹簦” “怎么了?”我有些...
    開封第一講書人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵殖蚕,是天一觀的道長(zhǎng)轿衔。 經(jīng)常有香客問我,道長(zhǎng)睦疫,這世上最難降的妖魔是什么害驹? 我笑而不...
    開封第一講書人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮蛤育,結(jié)果婚禮上宛官,老公的妹妹穿的比我還像新娘。我一直安慰自己瓦糕,他們只是感情好底洗,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著咕娄,像睡著了一般亥揖。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,441評(píng)論 1 310
  • 那天费变,我揣著相機(jī)與錄音摧扇,去河邊找鬼。 笑死挚歧,一個(gè)胖子當(dāng)著我的面吹牛扛稽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播滑负,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼在张,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了矮慕?” 一聲冷哼從身側(cè)響起帮匾,我...
    開封第一講書人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎凡傅,沒想到半個(gè)月后辟狈,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡夏跷,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年哼转,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片槽华。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡壹蔓,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出猫态,到底是詐尸還是另有隱情佣蓉,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布亲雪,位于F島的核電站勇凭,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏义辕。R本人自食惡果不足惜虾标,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望灌砖。 院中可真熱鬧璧函,春花似錦、人聲如沸基显。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽撩幽。三九已至库继,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背宪萄。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工舅桩, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人雨膨。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像读串,于是被迫代替她去往敵國(guó)和親聊记。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359

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

  • 在iOS中隨處都可以看到絢麗的動(dòng)畫效果恢暖,實(shí)現(xiàn)這些動(dòng)畫的過程并不復(fù)雜排监,今天將帶大家一窺ios動(dòng)畫全貌。在這里你可以看...
    每天刷兩次牙閱讀 8,514評(píng)論 6 30
  • 在iOS中隨處都可以看到絢麗的動(dòng)畫效果杰捂,實(shí)現(xiàn)這些動(dòng)畫的過程并不復(fù)雜舆床,今天將帶大家一窺iOS動(dòng)畫全貌。在這里你可以看...
    F麥子閱讀 5,115評(píng)論 5 13
  • 前言 本文只要描述了iOS中的Core Animation(核心動(dòng)畫:隱式動(dòng)畫嫁佳、顯示動(dòng)畫)挨队、貝塞爾曲線、UIVie...
    GitHubPorter閱讀 3,636評(píng)論 7 11
  • 在iOS實(shí)際開發(fā)中常用的動(dòng)畫無非是以下四種:UIView動(dòng)畫蒿往,核心動(dòng)畫盛垦,幀動(dòng)畫,自定義轉(zhuǎn)場(chǎng)動(dòng)畫瓤漏。 1.UIView...
    請(qǐng)叫我周小帥閱讀 3,112評(píng)論 1 23
  • 轉(zhuǎn)載:http://www.cnblogs.com/jingdizhiwa/p/5601240.html 1.ge...
    F麥子閱讀 1,551評(píng)論 0 1