美文网首页
02.6-Core Animation(核心动画)

02.6-Core Animation(核心动画)

作者: weyan | 来源:发表于2018-11-26 08:31 被阅读0次
    image.png

    一、CABasicAnimation

    1.红色的view向下平移400

    #import "ViewController.h"
    
    @interface ViewController ()
    @property (weak, nonatomic) IBOutlet UIView *redView;
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
    }
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
        //1.创建动画对象
        CABasicAnimation *anim  = [CABasicAnimation animation];
        //2.设置动画属性.
        anim.keyPath = @"position.y";
        anim.toValue = @(400);
        
        //动画完成时会自动删除动画
        anim.removedOnCompletion = NO;
        
        //动画完成时保持什么状态
        anim.fillMode = kCAFillModeForwards;
        
        //添加动画
        [self.redView.layer addAnimation:anim forKey:@"anim1"];
        
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    

    2.心跳效果

    #import "ViewController.h"
    
    @interface ViewController ()
    @property (weak, nonatomic) IBOutlet UIImageView *imageView;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
    }
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        
        //1.创建动画对象
        CABasicAnimation *anim = [CABasicAnimation animation];
        //2.设置动画属性
        anim.keyPath = @"transform.scale";
        anim.toValue = @0;
        
        //设置执行次数
        anim.repeatCount = HUGE;
        anim.duration = 0.5;
        
        //自动返转(怎么去,怎么回来)
        anim.autoreverses = YES;
        
        //3.添加动画
        [self.imageView.layer addAnimation:anim forKey:@"scaleAnim"];
        
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    @end
    

    二、CAKeyFrameAnimation

    #import "ViewController.h"
    
    @interface ViewController ()
    @property (weak, nonatomic) IBOutlet UIImageView *iconImageView;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
    }
    
    #define  angleToRadio(angle) ((angle) * M_PI / 180.0)
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        
        //可以根据路径做动画
        CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];
        
        anim.keyPath = @"transform.rotation";
        //进行多个值之间的动画
        anim.values = @[@(angleToRadio(-5)),@(angleToRadio(5)),@(angleToRadio(-5))];
        anim.repeatCount = MAXFLOAT;
        
        //anim.autoreverses = YES;
    
        anim.duration = 0.1;
        
        //添加动画
        [self.iconImageView.layer addAnimation:anim forKey:nil];
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    @end
    

    1.路径动画--让小鱼在里面按照我们设置的路径持续游动

    #import "ViewController.h"
    
    @interface ViewController ()
    
    /** <#注释#>*/
    @property (nonatomic ,weak) CALayer *fistLayer;
    
    @property (strong, nonatomic)  NSMutableArray *imageArray;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        //设置背景
        self.view.layer.contents = (id)[UIImage imageNamed:@"bg"].CGImage;
        
        CALayer *fistLayer = [CALayer layer];
        fistLayer.frame = CGRectMake(100, 288, 89, 40);
        //fistLayer.backgroundColor = [UIColor redColor].CGColor;
        [self.view.layer addSublayer:fistLayer];
        self.fistLayer = fistLayer;
        
        //加载图片
        NSMutableArray *imageArray = [NSMutableArray array];
        for (int i = 0; i < 10; i++) {
           UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"fish%d",i]];
            [imageArray addObject:image];
        }
        self.imageArray = imageArray;
        //添加定时器
        [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(update) userInfo:nil repeats:YES];
        
        //添加核心动画
        CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];
        anim.keyPath = @"position";
        
        UIBezierPath *path = [UIBezierPath bezierPath];
        [path moveToPoint:CGPointMake(100, 288)];
        [path addLineToPoint:CGPointMake(100, 100)];
        [path addLineToPoint:CGPointMake(300, 100)];
        [path addQuadCurveToPoint:CGPointMake(300, 600) controlPoint:CGPointMake(400, 600)];
        [path addLineToPoint:CGPointMake(100, 288)];
        
        //设置路径
        anim.path = path.CGPath;
        anim.duration = 5.0;
        anim.repeatCount = HUGE;
        //根据路径,自动旋转
        anim.rotationMode = @"autoReverse";
        
        //设置时间计算模型
        anim.calculationMode = @"cubic";
        
        [self.fistLayer addAnimation:anim forKey:@"moveAnim"];
        
    }
    
    static int _imageIndex = 0;
    - (void)update {
        
        //从数组当中取出图片
        UIImage *image = self.imageArray[_imageIndex];
        self.fistLayer.contents = (id)image.CGImage;
        _imageIndex++;
        if (_imageIndex > 9) {
            _imageIndex = 0;
        }
    }
    
    @end
    

    三、CATransition (转场动画)

    #import "ViewController.h"
    
    @interface ViewController ()
    @property (weak, nonatomic) IBOutlet UIImageView *imageV;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
    }
    
    static int _imageIndex = 0;
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        
        //转场代码必须得要与转场动画在同一个方法当中.
        _imageIndex++;
        if (_imageIndex == 5) {
            _imageIndex = 0;
        }
        
        NSString *imageName = [NSString stringWithFormat:@"%d",_imageIndex];
        self.imageV.image = [UIImage imageNamed:imageName];
        
        //转场动画
        //添加动画
        CATransition *anim = [CATransition animation];
        //转场类型
        anim.type = @"pageCurl";
        //设置方向
        anim.subtype = @"fromTop";
        
        //从哪个位置开始动画
        anim.startProgress = 0.2;
        //到哪个位置结束
        anim.endProgress = 0.5;
        //动画持续时间
        anim.duration = 1.0;
        [self.imageV.layer addAnimation:anim forKey:nil];
        
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    @end
    

    四、CAAnimationGroup (动画组)

    #import "ViewController.h"
    
    @interface ViewController ()
    @property (weak, nonatomic) IBOutlet UIView *redView;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
    }
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        
        CABasicAnimation *anim = [CABasicAnimation animation];
        anim.keyPath = @"position.y";
        anim.toValue = @400;
        anim.duration = 1.0;
        //anim.removedOnCompletion = NO;
        //anim.fillMode = kCAFillModeForwards;
        //[self.redView.layer addAnimation:anim forKey:nil];
        
        CABasicAnimation *anim2 = [CABasicAnimation animation];
        anim2.keyPath = @"transform.scale";
        anim2.toValue = @0.5;
        anim2.duration = 1.0;
        //anim2.removedOnCompletion = NO;
        //anim2.fillMode = kCAFillModeForwards;
        //[self.redView.layer addAnimation:anim2 forKey:nil];
        
        CAAnimationGroup *groupAnim = [CAAnimationGroup animation];
        groupAnim.animations = @[anim, anim2];;
        //把数组当中的所有动画给添加到layer
        groupAnim.removedOnCompletion = NO;
        groupAnim.duration = 1.0;
        groupAnim.fillMode  = kCAFillModeForwards;
        [self.redView.layer addAnimation:groupAnim forKey:nil];
        
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    @end
    

    五、核心动画案列

    1.图片折叠

    #import "ViewController.h"
    
    @interface ViewController ()
    
    @property (weak, nonatomic) IBOutlet UIImageView *topImageView;
    
    @property (weak, nonatomic) IBOutlet UIImageView *bottomImageView;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        //上部图片只显示上半部分
        self.topImageView.layer.contentsRect = CGRectMake(0, 0, 1, 0.5);
        //下部图片只显示下半部分
        self.bottomImageView.layer.contentsRect = CGRectMake(0, 0.5, 1, 0.5);
        
        self.topImageView.layer.anchorPoint = CGPointMake(0.5, 1);
        self.bottomImageView.layer.anchorPoint =  CGPointMake(0.5, 0);
        
    }
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        
        [UIView animateWithDuration:0.5 animations:^{
           
            self.topImageView.layer.transform = CATransform3DMakeRotation(M_PI, 1, 0, 0);
        }];
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    @end
    

    2.图片折叠(添加平移手势)

    #import "ViewController.h"
    
    @interface ViewController ()
    
    @property (weak, nonatomic) IBOutlet UIImageView *topImageView;
    
    @property (weak, nonatomic) IBOutlet UIImageView *bottomImageView;
    
    @property (weak, nonatomic) IBOutlet UIView *dragerView;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        //上部图片只显示上半部分
        self.topImageView.layer.contentsRect = CGRectMake(0, 0, 1, 0.5);
        //下部图片只显示下半部分
        self.bottomImageView.layer.contentsRect = CGRectMake(0, 0.5, 1, 0.5);
        
        self.topImageView.layer.anchorPoint = CGPointMake(0.5, 1);
        self.bottomImageView.layer.anchorPoint =  CGPointMake(0.5, 0);
        
        //添加手势
        UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
        [self.dragerView addGestureRecognizer:pan];
        
    }
    
    - (void)pan:(UIPanGestureRecognizer *)pan {
        //上部图片开始旋转
        CGPoint transP = [pan translationInView:pan.view];
        
        //当y偏移量为200时旋转180度
        CGFloat angle = transP.y * M_PI / 200.0;
        
        CATransform3D transform = CATransform3DIdentity;
        
        //300.0眼睛离屏幕的距离(近大远小)
        transform.m34 = -1 / 300.0;
        
        self.topImageView.layer.transform = CATransform3DRotate(transform, -angle, 1, 0, 0);
        
        
    }
    
    
    //- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    //    
    //    [UIView animateWithDuration:0.5 animations:^{
    //       
    //        self.topImageView.layer.transform = CATransform3DMakeRotation(M_PI, 1, 0, 0);
    //    }];
    //}
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    @end
    

    3、图片折叠(渐变效果)

    #import "ViewController.h"
    
    @interface ViewController ()
    
    @property (weak, nonatomic) IBOutlet UIImageView *topImageView;
    
    @property (weak, nonatomic) IBOutlet UIImageView *bottomImageView;
    
    @property (weak, nonatomic) IBOutlet UIView *dragerView;
    
    @property (weak, nonatomic) CAGradientLayer *gradientL;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        //上部图片只显示上半部分
        self.topImageView.layer.contentsRect = CGRectMake(0, 0, 1, 0.5);
        //下部图片只显示下半部分
        self.bottomImageView.layer.contentsRect = CGRectMake(0, 0.5, 1, 0.5);
        
        self.topImageView.layer.anchorPoint = CGPointMake(0.5, 1);
        self.bottomImageView.layer.anchorPoint =  CGPointMake(0.5, 0);
        
        //添加手势
        UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
        [self.dragerView addGestureRecognizer:pan];
        
        //渐变层
        CAGradientLayer *gradientL = [CAGradientLayer layer];
    
        //设置渐变的颜色
        gradientL.colors = @[
                             (id)[UIColor clearColor].CGColor,
                             (id)[UIColor blackColor].CGColor
                             ];
        
        //设置图层的不透明度
        gradientL.opacity = 0;
        
        gradientL.frame = self.bottomImageView.bounds;
        [self.bottomImageView.layer addSublayer:gradientL];
        
        self.gradientL = gradientL;
    }
    
    - (void)gradientLayer {
        
        //渐变层
        CAGradientLayer *gradientL = [CAGradientLayer layer];
        
        //设置渐变的颜色
        gradientL.colors = @[
                             (id)[UIColor redColor].CGColor,
                             (id)[UIColor greenColor].CGColor,
                             (id)[UIColor blueColor].CGColor
                             ];
        
        //设置渐变的方向
        gradientL.startPoint = CGPointMake(0, 0);
        gradientL.endPoint = CGPointMake(1, 0);
        
        //设置渐变的起始位置 (从哪个点开始渐变到下一个颜色)
        gradientL.locations = @[@0.2,@0.8];
        
        gradientL.frame = self.bottomImageView.bounds;
    }
    
    - (void)pan:(UIPanGestureRecognizer *)pan {
    
        //上部图片开始旋转
        CGPoint transP = [pan translationInView:pan.view];
        
        //当y偏移量为200时旋转180度
        CGFloat angle = transP.y * M_PI / 200.0;
        
        //添加透视效果
        CATransform3D transform = CATransform3DIdentity;
        //300.0眼睛离屏幕的距离(近大远小)
        transform.m34 = -1 / 300.0;
        
        self.topImageView.layer.transform = CATransform3DRotate(transform, -angle, 1, 0, 0);
        
        //设置渐变层的不透明度
        CGFloat opacity = transP.y * 1 / 200.0;;
        self.gradientL.opacity = opacity;
        
        //当手指松开时,返弹动画
        if (pan.state == UIGestureRecognizerStateEnded) {
            
            self.gradientL.opacity = 0;
            
            //SpringWithDamping:弹性系数 值越小,弹性越大
            [UIView animateWithDuration:1.0 delay:0 usingSpringWithDamping:0.25 initialSpringVelocity:0 options:UIViewAnimationOptionCurveLinear animations:^{
                
                //复位
                self.topImageView.layer.transform = CATransform3DIdentity;
                
            } completion:nil];
            
        }
    }
    
    @end
    

    4、音乐震动条

    #import "ViewController.h"
    
    @interface ViewController ()
    
    @property (weak, nonatomic) IBOutlet UIView *contentView;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        //1怎么样使用复制层?
        //1.创建复制层
        //2.往复制层里面添加子层
        //3.设置复制的份数
        //4.设置对复制出来的子层做形变操作
        //5.设置子层的动画延时执行时间
      
        //复制层(可以复制里面的子层)
        CAReplicatorLayer *repL = [CAReplicatorLayer layer];
        repL.frame = self.contentView.bounds;
        [self.contentView.layer addSublayer:repL];
        
        CALayer *layer = [CALayer layer];
        CGFloat H = 150;
        //CGFloat Y = self.contentView.bounds.size.height - H;
        layer.bounds = CGRectMake(0, 0, 30, H);
        layer.anchorPoint = CGPointMake(0, 1);
        layer.position = CGPointMake(0, self.contentView.bounds.size.height);
        
        layer.backgroundColor = [UIColor redColor].CGColor;
        [repL addSublayer:layer];
        
        //添加动画
        CABasicAnimation *anim = [CABasicAnimation animation];
        anim.keyPath = @"transform.scale.y";
        anim.toValue = @0;
        anim.repeatCount = HUGE;
        anim.duration  = 1.0;
        anim.autoreverses = YES;
        [layer addAnimation:anim forKey:nil];
        
        //复制的份数.(包括它自己)
        repL.instanceCount = 5;
        
        //动画延时执行时间
        repL.instanceDelay = 1.0;
        
        //对复制出来的子层做形变操作(相对于复制出来的上一个图层进行形变.)
        repL.instanceTransform  = CATransform3DMakeTranslation(45, 0, 0);
    }
    
    
    - (void)test {
        
        //复制层(可以复制里面的子层)
        CAReplicatorLayer *repL = [CAReplicatorLayer layer];
        repL.frame = self.contentView.bounds;
        repL.backgroundColor = [UIColor blueColor].CGColor;
        [self.contentView.layer addSublayer:repL];
        
        CALayer *layer = [CALayer layer];
        layer.frame = CGRectMake(50, 50, 30, 30);
        layer.backgroundColor = [UIColor redColor].CGColor;
        [repL addSublayer:layer];
        
        CALayer *layer2 = [CALayer layer];
        layer2.frame = CGRectMake(50, 150, 30, 30);
        layer2.backgroundColor = [UIColor redColor].CGColor;
        [repL addSublayer:layer2];
        
        //复制的份数.(包括它自己)
        repL.instanceCount = 5;
        
        //对复制出来的子层做形变操作(相对于复制出来的上一个图层进行形变.)
        repL.instanceTransform  = CATransform3DMakeTranslation(45, 0, 0);
        
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    @end
    

    5、倒影


    #import "ViewController.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        NSLog(@"%@",self.view.layer);
        
        CAReplicatorLayer *repL = (CAReplicatorLayer *)self.view.layer;
        //设置复制2份
        repL.instanceCount = 2;
        
        //绕着复制层的锚点进行旋转
        repL.instanceTransform = CATransform3DMakeRotation(M_PI, 1, 0, 0);
        
        //对复制出来的子层颜色进行修改
        repL.instanceRedOffset -= 0.1;
        repL.instanceGreenOffset -= 0.1;
        repL.instanceBlueOffset -= 0.1;
        repL.instanceAlphaOffset -= 0.1;
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    @end
    

    UIView和核心动画区别

    UIView与核心动画区别?
    1.核心动画只作用在layer上
    2.核心动画看到一切都是假像.并没有去修改属性的真实值.

    什么时候使用核心动画什么时候使用UIView动画
    当需要与用户进行交互时,必须得要使用UIView动画

    做帧动画时 当根据路径做动画时,使用核心动画
    做转场动画时,使用核心动画,转场类型比较多.

    相关文章

      网友评论

          本文标题:02.6-Core Animation(核心动画)

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