Animation筆記

layer是動(dòng)畫的核心

1 通過自定義layer繪制簡單線條
MYLayer繼承自CALayer

#import "MYLayer.h"

@implementation MYLayer

-(void)drawInContext:(CGContextRef)ctx{
    CGMutablePathRef thePath = CGPathCreateMutable();
    
    CGPathMoveToPoint(thePath,NULL,20.0f,100.f);
    CGPathAddCurveToPoint(thePath,
                          NULL,
                          15.f,250.0f,
                          295.0f,250.0f,
                          295.0f,450.0f);
    
    CGContextBeginPath(ctx);
    CGContextAddPath(ctx, thePath);
    
    CGContextSetLineWidth(ctx, 5);
    CGContextStrokePath(ctx);
    
    // Release the path
    CFRelease(thePath);
}
@end

2 UIImageView設(shè)置圖片過小時(shí)太模糊
就算設(shè)置了imageView.contentMode = UIViewContentModeScaleAspectFit;也不行,解決方案為設(shè)置下imageView的layer的contentsGravity屬性為kCAGravityCenter即可。
截取contentsGravity的定義:

contentsGravity.png

3 CABasicAnimation最基礎(chǔ)的動(dòng)畫

設(shè)置好屬性后直接應(yīng)用在layer上

  CABasicAnimation *fade = [CABasicAnimation animationWithKeyPath:@"shadowOpacity"];
    fade.fromValue = [NSNumber numberWithFloat:1.0];
    fade.toValue = [NSNumber numberWithFloat:0.0];
    fade.duration = 2.0f;
    [layer addAnimation:fade forKey:@"shadowOpacity"];
注意動(dòng)畫只是模擬一個(gè)假的過程,layer的shadowOpacity其實(shí)是沒有改變的 ,所以如果真的需要改變屬性的值,記得在動(dòng)畫完畢后設(shè)置一下:
 layer.shadowOpacity = 0;

4、CAKeyframeAnimation

//創(chuàng)建一個(gè)路徑
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path, NULL, 0, 64);
    CGPathAddCurveToPoint(path, NULL, SCREEN_WIDTH -20, 100, 20, SCREEN_HEIGHT * 0.5, SCREEN_WIDTH, SCREEN_HEIGHT);
    CAKeyframeAnimation *keyAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    keyAnimation.path = path;
    keyAnimation.duration = 10.0f;
    [layer addAnimation:keyAnimation forKey:@"position"];

5 組合動(dòng)畫

    //改borderWidth
    CAKeyframeAnimation *widthAnim = [CAKeyframeAnimation animationWithKeyPath:@"borderWidth"];
    NSArray* widthValues = [NSArray arrayWithObjects:@10.0, @5.0, @1.0,@10.0, @5.0, @1.0,@10.0, @5.0, @1.0, nil];
    widthAnim.values = widthValues;
    widthAnim.calculationMode = kCAAnimationPaced;
    
    //改borderColor
    CAKeyframeAnimation *colorAnim = [CAKeyframeAnimation animationWithKeyPath:@"borderColor"];
    NSArray *colorValues = [NSArray arrayWithObjects:(id)[UIColor redColor].CGColor,(id)[UIColor greenColor].CGColor,(id)[UIColor orangeColor].CGColor, nil];
    colorAnim.values = colorValues;
    colorAnim.calculationMode = kCAAnimationPaced;
    
    CAAnimationGroup *group = [[CAAnimationGroup alloc] init];
    group.animations = @[widthAnim,colorAnim];
    group.duration = 2.0f;
    
    [imageView.layer addAnimation:group forKey:@"borderChanged"];

效果就是一邊改border寬度,一邊變換顏色


twoAnimation.gif

6 UIView動(dòng)畫和CA動(dòng)畫一起使用

原文: As a result, changes you make to the layer are automatically reflected by the view object as well. This behavior means that you can use either the Core Animation or UIView interfaces to make your changes.

 [UIView animateWithDuration:1.0 animations:^{
        // Change the opacity implicitly.
        imageView.layer.opacity = 0.1;
        
        // Change the position explicitly.
        CABasicAnimation* theAnim = [CABasicAnimation animationWithKeyPath:@"position"];
        theAnim.fromValue = [NSValue valueWithCGPoint:imageView.layer.position];
        theAnim.toValue = [NSValue valueWithCGPoint:CGPointMake(0, SCREEN_HEIGHT)];
        theAnim.duration = 3.0;
        [imageView.layer addAnimation:theAnim forKey:@"AnimateFrame"];
    }];
    

7 CATransition動(dòng)畫
In the example, both myView1 and myView2 are located at the same position in the same parent view but only myView1 is currently visible. The push transition causes myView1 to slide out to the left and fade until it is hidden while myView2 slides in from the right and becomes visible. Updating the hidden property of both views ensures that the visibility of both views is correct at the end of the animation.

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;

效果:


transition.gif

8動(dòng)畫暫停與恢復(fù)

//暫停
-(void)pauseAnim{
    CFTimeInterval pauseTime = [imageView.layer convertTime:CACurrentMediaTime() toLayer:nil];
    imageView.layer.speed = 0.0;
    imageView.layer.timeOffset  = pauseTime;
}
//恢復(fù)
-(void)resumeAnim{
    CFTimeInterval pausedTime = [imageView.layer timeOffset];
    imageView.layer.speed = 1.0;
    imageView.layer.timeOffset = 0;
    imageView.layer.beginTime = 0;
    CFTimeInterval timeSincePause = [imageView.layer convertTime:CACurrentMediaTime() toLayer:nil] - pausedTime;
    imageView.layer.beginTime = timeSincePause;
}
 timeOffset的作用:
比如有個(gè)動(dòng)畫整個(gè)過程需要三秒,如果設(shè)置該動(dòng)畫的timeOffset為一秒,那么這個(gè)動(dòng)畫為從原先設(shè)計(jì)好的流程中的第一秒結(jié)束的位置直接開始執(zhí)行,這樣2秒后其實(shí)就走完了,但是記住timeOffset只會影響動(dòng)畫的執(zhí)行開始位置,動(dòng)畫的整個(gè)過程還是要執(zhí)行的,所以接著動(dòng)畫會執(zhí)行開頭錯(cuò)過的那第一秒的動(dòng)畫。
所以以上的流程就是:
1.首先獲取到點(diǎn)擊暫停是的layer運(yùn)行時(shí)間,取這段時(shí)間出來然后儲存在timeOffset中。
2.恢復(fù)動(dòng)畫時(shí),首先獲取到當(dāng)前l(fā)ayer的timeOffset,也就是之前走了多少了,然后用獲取到的當(dāng)前時(shí)間減去timeOffset,就是應(yīng)該從其實(shí)位置偏移多少,從這開始執(zhí)行就可以了beginTime(個(gè)人理解,如果有誤請?zhí)岢觯?

效果:


Jietu20180112-112444-HD.gif
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容