美文网首页iOS技术点iOS图形处理相关iOS
ios史上最详细的动画讲解-加载等待动画(一)

ios史上最详细的动画讲解-加载等待动画(一)

作者: mark666 | 来源:发表于2016-07-04 14:01 被阅读17232次

    前言

    本文主要面向的对象是那些没有动画基础的入门引导,提供一个学习动画的正确途径,并且配以项目实战的效果的重点讲解。

    正文

    这篇文章要实现的效果如下图

    效果图

    实现这个效果需要了解基本概念
    http://www.cnblogs.com/mjios/tag/objective-c/default.html?page=2
    这个是明杰大神的入门讲解,

    基础

    你需要从这几篇文章中了解到以下的知识点

    • UIViewCALayer之间的关系(区别和联系)
    • Core Animation框架中使用的类
    • CALayerCore Animation之间的联系
    • CAAnimation的常用属性

    如果你对这些基本的知识点已经全部理清楚,那么接下来你就可以继续往下看了,我们实现动画主要需要学习的类库QuartzCore,首先看一下这个类库

    QuartzCore
    首先有我们熟悉的CALayer``CAAnimation,对于从来没有做过动画的朋友来说,其他的类就不清楚了。下面我就简单介绍一下主要的类之间关系,以及单独类主要实现什么。
    • CAAnimation.h主要是各类动画的基类,我们一般不会使用它来做动画。基本常用属性
    //公有属性定义动画的节奏
    @property(nullable, strong) CAMediaTimingFunction *timingFunction;
    //代理,例如捕捉动画的开始,动画的结束等
    @property(nullable, strong) id delegate;
    //动画执行完是否移除
    @property(getter=isRemovedOnCompletion) BOOL removedOnCompletion;
    
    • CABase.h可以忽略不看,是一些基本的配置

    • CADisplayLink.h帧动画,默认添加定时器,每秒刷多少帧,在gitHub上有facebook出品的一个pop动画,据说是居于帧动画
      https://github.com/facebook/pop

    • CAEAGLLayer是和<OpenGLES/EAGLDrawable.h>这个框架联合使用的,暂时用不到。

    • CAEmitter相关的是粒子动画,可以实现很多酷炫的效果

    • CAShapeLayer非常重要的一个类,常常与UIKit框架的UIBezierPath贝塞尔曲线联合使用,绘制曲线,圆形,各种复杂的图形都会使用到,非常非常重要,我的上一篇文章就是他们两个的结合

    • CAGradientLayer常见应用于锁屏底部闪烁的滑动来解锁。

    • CAReplicatorLayer 它独有的特性是,其子类具有相同的属性,这篇文章主要是它的应用。

    其他的类,我是没有使用过,所以不做讲解。

    下面我们看就上述动画讲解一个最简单,三个点加载动画,作为入门。

        CAReplicatorLayer *replicatorLayer = [CAReplicatorLayer layer];
        replicatorLayer.bounds          = CGRectMake(0, 0, 100, 100);
        replicatorLayer.cornerRadius    = 10.0;
        replicatorLayer.position        =  self.view.center;
        replicatorLayer.backgroundColor = [UIColor colorWithRed:0.1 green:0.1 blue:0.1 alpha:0.2].CGColor;
    
    [self.view.layer addSublayer:replicatorLayer];
    
    

    那么我们会看到这个效果

    replicatorLayer

    接下来我们需要添加点

    CALayer *dotLayer        = [CALayer layer];
        dotLayer.bounds          = CGRectMake(0, 0, 15, 15);
        dotLayer.position        = CGPointMake(15, replicatorLayer.frame.size.height/2 );
        dotLayer.backgroundColor = [UIColor colorWithRed:0.1 green:0.1 blue:0.1 alpha:0.6].CGColor;
        dotLayer.cornerRadius    = 7.5;
        
        [replicatorLayer addSublayer:dotLayer];
    

    效果图

    接下来我们会想在创建两个点,然后做动画就可以,不错这是一种可实现的思路,可以如果我们要做第一中类似旋转的动画,我们需要创建10个点,难道我们一个个去创建吗?我们现在使用的是CAReplicatorLayer,它有个属性instanceCount,是子类的个数,然后我们设置每个子类的位置即可

    在上述代码添加

        replicatorLayer.instanceCount = 3;
        replicatorLayer.instanceTransform = CATransform3DMakeTranslation(replicatorLayer.frame.size.width/3, 0, 0);
    

    效果


    需要说明的是instanceTransform这个属性,它的作用是设置每个子Layer如何变化。CATransform3DMakeTranslation这个类的含义是使Layer根据X、Y、Z轴进行平移。我们需要的是平移,所以使用translation这个属性,如果我们是第一种圆形排放,那么我们需要这样设置

        CGFloat count                     =  10.0;
        replicatorLayer.instanceCount     = count;
        CGFloat angel                     = 2* M_PI/count;
        replicatorLayer.instanceTransform = CATransform3DMakeRotation(angel, 0, 0, 1);
    

    解释一下CATransform3DMakeRotation,它是CATransform3D的一个结构(矩阵结构),含义是使Layer在X、Y、Z轴根据给定的角度旋转。我们需要平面旋转则坐标系为(0,0,1)。
    看效果


    接下来我们需要添加动画

    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
        animation.duration    = 1.0;
        animation.fromValue   = @1;
        animation.toValue     = @0;
        animation.repeatCount = MAXFLOAT;
        [dotLayer addAnimation:animation forKey:nil];
    

    编译运行看效果:


    这不是我们需要的真实效果,我们还需要设置每一个sublayerinstanceDelay属性。

    replicatorLayer.instanceDelay = 1.0/3;
    

    编译运行看效果


    我们会发现动画在开始前会有不流畅效果,我们应该给dotLayer一个初始的大小
    dotLayer.transform = CATransform3DMakeScale(0, 0, 0);
    

    这样我们就能实现这个比较简单的等待动画效果。

    下面我们总结一下实现这个动画的步骤:

    • 1.首先创建一个可复用的CAReplicatorLayer,创建这个的目的是为了我添加的子类可以复用,一劳永逸;

    • 2.添加子Layer,设置子Layer所需要的样式;

    • 3.将子layer添加到CAReplicatorLayer上,并设置子layer个数和排布;

    • 4.给子layer添加动画效果,特别提醒一点transform一般针对的是缩放和旋转动画,当然也可以实现平移动画。

    下面我总结一下常用动画的 keyPath

    transform.rotation:旋转动画。
    transform.rotation.x:按x轴旋转动画。
    transform.rotation.y:按y轴旋转动画。
    transform.rotation.z:按z轴旋转动画。
    transform.scale:按比例放大缩小动画。
    transform.scale.x:在x轴按比例放大缩小动画。
    transform.scale.y:在y轴按比例放大缩小动画。
    transform.scale.z:在z轴按比例放大缩小动画。
    position:移动位置动画。
    opacity:透明度动画。

    最后向大家再分享一个闪烁的动画,本来这是一篇单独的文章,投稿首页已经通过审核,结果本人手贱不小心给删除了这篇文章,所以在这篇文章补上,这里只附swift代码,oc代码demo中查看。
    首先我们看一下效果:


    闪烁动画的实现主要是通过改变透明度,从而达成闪烁的效果,我将这个方法写成了一个分类,给CABasicAnimation添加一个分类,具体代码如下
    import UIKit
    
    class catergory: CABasicAnimation {
    
        
       class func opacityForever_Animation(time : NSTimeInterval) -> CABasicAnimation {
            
            
            let animation = CABasicAnimation(keyPath:"opacity")
            animation.fromValue = 1
            animation.toValue = 0
            animation.duration = time
            animation.autoreverses = true
            animation.removedOnCompletion = false
            animation.fillMode = kCAFillModeForwards
            animation.timingFunction = CAMediaTimingFunction.init(name: kCAMediaTimingFunctionEaseIn)
    
            return animation
        }
    
    }
    

    这样我们在外部可以给任何一个UIView添加闪烁动画。

    结尾

    本文具体实现的代码上传gitHub,demo中对这些动画进行了简单的封装,一是为了提高代码的质量和可读性,二是为了更符合项目实战,希望你在阅读的时候提出宝贵的意见,当然也欢迎你的Star。
    下一篇文章主要是想分享一下CAShapeLayer和贝塞尔曲线结合的例子,当然你有更好的动画效果希望你能私信推荐给我,我会选择一些好的实现并分享。
    https://github.com/markdashi/LoadingAnimation

    相关文章

      网友评论

      • 杏仁丶:感谢分享~
      • 西叶lv:那几篇文章能弄个链接么?
        西叶lv:@mark666 哦哦,没事了
        mark666:@郝嘉律 ???
      • ForestL:请问博主,三个点那个动画,可以设置三个点的背景颜色不一样吗?
      • 郑明明:写的不错嘛,很详细,纯手工定制动画,有质量,不过我喜欢封装的嘿嘿
      • Wang66:楼主,你好。
        当CALayer添加在CAReplicatorLayer上时,怎么设置CALayer的position属性?
      • 33a02bf71691:有没有什么办法可以让点的颜色不一样呢 假如三点的 当前的点颜色亮一些 其他俩点颜色相对暗一些
      • cbb9e3ec600d:非常有用,赞一个
      • 我在普陀山下:稳得一塌糊涂
        mark666:@我在南极洲 ?
      • 380ad0f2110c:拖拽的时候怎么才能保持动画 :joy:
        mark666:@不锈钢小猪 什么意思?
        380ad0f2110c:@不锈钢小猪 :sweat_smile: 找到了,原来楼主已经写好了
      • 无涯子:最后那个 catergory 要怎么使用?
      • ca7508dad23b:真棒!
      • PPAbner:爱鲜蜂工作?
        mark666:@PP_Abner ???
        PPAbner:@PP_Abner 模拟器!
        mark666:@PP_Abner 从哪里看出来的?
      • __夏至未至:谢谢分享,学到了很多呢。不过有个小小的建议,就是把把loadView.backgroundColor 设置成 [UIColor colorWithWhite:1 alpha:0];这样既不会遮挡ViewController里本来的UI了,也可以显示这个HUD动画。 :blush: 继续跟着大兄弟学动画
        mark666:@__夏至未至 这是可以的!
      • xxttw:不错啊
      • 389c20d5a244:写的不错
      • ShayneFcf:好样的!期待更多

      本文标题:ios史上最详细的动画讲解-加载等待动画(一)

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