美文网首页
Animation笔记

Animation笔记

作者: koreadragon | 来源:发表于2018-01-10 16:36 被阅读23次

layer是动画的核心

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设置图片过小时太模糊
就算设置了imageView.contentMode = UIViewContentModeScaleAspectFit;也不行,解决方案为设置下imageView的layer的contentsGravity属性为kCAGravityCenter即可。
截取contentsGravity的定义:

contentsGravity.png

3 CABasicAnimation最基础的动画

设置好属性后直接应用在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"];
注意动画只是模拟一个假的过程,layer的shadowOpacity其实是没有改变的 ,所以如果真的需要改变属性的值,记得在动画完毕后设置一下:
 layer.shadowOpacity = 0;

4、CAKeyframeAnimation

//创建一个路径
    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 组合动画

    //改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动画和CA动画一起使用

原文: 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动画
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动画暂停与恢复

//暂停
-(void)pauseAnim{
    CFTimeInterval pauseTime = [imageView.layer convertTime:CACurrentMediaTime() toLayer:nil];
    imageView.layer.speed = 0.0;
    imageView.layer.timeOffset  = pauseTime;
}
//恢复
-(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的作用:
比如有个动画整个过程需要三秒,如果设置该动画的timeOffset为一秒,那么这个动画为从原先设计好的流程中的第一秒结束的位置直接开始执行,这样2秒后其实就走完了,但是记住timeOffset只会影响动画的执行开始位置,动画的整个过程还是要执行的,所以接着动画会执行开头错过的那第一秒的动画。
所以以上的流程就是:
1.首先获取到点击暂停是的layer运行时间,取这段时间出来然后储存在timeOffset中。
2.恢复动画时,首先获取到当前layer的timeOffset,也就是之前走了多少了,然后用获取到的当前时间减去timeOffset,就是应该从其实位置偏移多少,从这开始执行就可以了beginTime(个人理解,如果有误请提出)

效果:


Jietu20180112-112444-HD.gif

相关文章

网友评论

      本文标题:Animation笔记

      本文链接:https://www.haomeiwen.com/subject/hnionxtx.html