0、动画基础

  • 主要动画属性

        1、XY坐标属性:Position(左上角为原点)

        2、透明度属性:Opacity(透明:0.0,不透明:1.0)

        3、缩放属性:Scale(调整对象的尺寸,如对话框的显示)

        4、其他属性:Color(颜色属性)、Rotate(旋转属性)、3D属性(如3D翻转)

  • 思考动画是如何形成的
    1、动画开始时对象的属性
    2、动画结束时对象的属性
    3、动画执行的时间
    4、在动画执行过程中会发生什么
    5、动画结束后会发生什么
  • 动画曲线
    1、线性匀速变化(Linear)
    2、以慢速开始:加速变化(Ease In)
    3、先加速后减速的变化(Ease In,Ease Out)
    4、以慢速结束:减速变化(Ease Out)


1、UIKit和Core Animation

  • 架构

         

UIKit(iOS) and Appkit(OS X)
                        Core Animation
          OpenGL ES and OpenGL    Core Graphics
                      Graphics Hardware
  • 实例

       

//创建
        let redBall = UIView(frame: CGRectMake(50, 50, 100, 100))
        redBall.backgroundColor = UIColor.redColor()
        redBall.layer.cornerRadius = 50
        self.view.addSubview(redBall)
        
        //球的放大动画
        UIView.animateWithDuration(0.5, delay: 0, options: UIViewAnimationOptions.CurveEaseInOut, animations: { () -> Void in
            redBall.transform = CGAffineTransformMakeScale(2, 2)
            }) { (finished:Bool) -> Void in
                print("finished")
        }

 

override func viewDidLoad() {
        super.viewDidLoad()
       //创建
        let redBall = UIView(frame: CGRectMake(50, 50, 100, 100))
        redBall.backgroundColor = UIColor.redColor()
        redBall.layer.cornerRadius = 50
        self.view.addSubview(redBall)
        
        //球的放大动画
        UIView.animateWithDuration(0.5, delay: 0, options: UIViewAnimationOptions.CurveEaseInOut, animations: { () -> Void in
            
//            redBall.transform = CGAffineTransformMakeScale(2, 2)
            //组合动画,CGAffineTransformConcat
            redBall.transform = CGAffineTransformConcat(CGAffineTransformMakeScale(2.0, 2.0), CGAffineTransformMakeTranslation(150, 50))
            
            }) { (finished:Bool) -> Void in
                print("finished")
        }
    }

组合动画:CGAffineTransformConcat


    o

verride func viewDidLoad() {
        super.viewDidLoad()
       //创建
        let redBall = UIView(frame: CGRectMake(50, 50, 100, 100))
        redBall.backgroundColor = UIColor.redColor()
        redBall.layer.cornerRadius = 50
        self.view.addSubview(redBall)
        
        //球的放大动画
        UIView.animateWithDuration(0.5, delay: 0, options: UIViewAnimationOptions.CurveEaseInOut, animations: { () -> Void in
            
//            redBall.transform = CGAffineTransformMakeScale(2, 2)
            //组合动画,CGAffineTransformConcat
            redBall.transform = CGAffineTransformConcat(CGAffineTransformMakeScale(2.0, 2.0), CGAffineTransformMakeTranslation(150, 50))
            redBall.backgroundColor = UIColor.greenColor()
            }) { (finished:Bool) -> Void in
                print("finished")
        }
    }

弹性动画(spring Animation),iOS 7.0以后有此动画

   

//创建
        let redBall = UIView(frame: CGRectMake(50, 50, 100, 100))
        redBall.backgroundColor = UIColor.redColor()
        redBall.layer.cornerRadius = 50
        self.view.addSubview(redBall)
        
        //弹性动画,iOS 7.0以后有此动画
        UIView.animateWithDuration(2.0, delay: 0, usingSpringWithDamping: 0.3,//弹性阻尼,取值范围是0-1,越接近0,动画的弹性效果就越明显;如果设置为1,则动画不会有弹性效果
            initialSpringVelocity: 0,//视图在动画开始时的速度,通常都应该传入0
            options: UIViewAnimationOptions.CurveEaseInOut, animations: { () -> Void in
                redBall.transform = CGAffineTransformConcat(
                    CGAffineTransformMakeScale(2, 2),CGAffineTransformMakeTranslation(150, 50)
                )
                
                redBall.backgroundColor = UIColor.greenColor()
                
            }) { (finished:Bool) -> Void in
                print("finished")
        }


2、JNWSpringAnimation,详细调整参数

前言

CAKeyframeAnimation(关键帧动画)

多个关键帧组成动画

可以设置时间间隔

设置位移,缩放等动画属性

JNW支持的属性

位置:position

边界:bounds

阴影:shadow

圆角:corner

缩放:scale

旋转:rotation

JNW帧率为6帧的动画,1秒6帧

  • 缩放动画


   

//创建
        let redBall = UIView(frame: CGRectMake(50, 50, 100, 100))
        redBall.backgroundColor = UIColor.redColor()
        redBall.layer.cornerRadius = 50
        self.view.addSubview(redBall)
        
        //缩放动画
        //创建JNW实例,keyPath跟CALayer一样
        let scale = JNWSpringAnimation(keyPath: "transform.scale")
        
        //阻尼固有频率是指有阻尼的机械系统的自由振动频率。由系统的质量、弹性系数和阻力系数决定,可表示为 式中:K为弹性系数;R为阻力系数,M为质量。
        
        //阻尼,决定动画的衰减,默认为30
        scale.damping = 6
        //弹性系数,弹簧伸缩的难度,决定动画的振幅,默认为300
        scale.stiffness = 100
        //质量,决定动画快慢的效果,默认为5
        scale.mass = 2
        //设置初始值
        scale.fromValue = 1
        //设置结束值
        scale.toValue = 2
        //将JNW赋予redball
        redBall.layer.addAnimation(scale, forKey: scale.keyPath)
        //jnwspring animation默认会还原初始状态,所以要手动设置到结束状态
        redBall.transform = CGAffineTransformMakeScale(2, 2)
  • 旋转动画

   

//创建
        let redBall = UIView(frame: CGRectMake(50, 50, 100, 100))
        redBall.backgroundColor = UIColor.redColor()
//        redBall.layer.cornerRadius = 50
        self.view.addSubview(redBall)
        
        //旋转动画
        //创建jnw对象
        let rotation = JNWSpringAnimation(keyPath: "transform.rotation")
        //设置阻尼值
        rotation.damping = 6
        //设置弹性系数
        rotation.stiffness = 100
        //设置质量
        rotation.mass = 2
        
        //设置初始值和结束值
        rotation.fromValue = 0
        rotation.toValue = M_PI_4
        
        redBall.layer.addAnimation(rotation, forKey: rotation.keyPath)
        //防止动画后还原
        redBall.transform = CGAffineTransformMakeRotation(CGFloat(M_PI_4))
  • 位移动画

     

//创建
        let redBall = UIView(frame: CGRectMake(50, 50, 100, 100))
        redBall.backgroundColor = UIColor.redColor()
//        redBall.layer.cornerRadius = 50
        self.view.addSubview(redBall)
        
        
        //位移动画
        //创建jnw对象
        let translation = JNWSpringAnimation(keyPath: "transform.translation.x")
        //设置阻尼值
        translation.damping = 6
        //设置弹性系数
        translation.stiffness = 100
        //设置质量
        translation.mass = 2
        
        //设置初始值和结束值
        translation.fromValue = 0
        translation.toValue = 100
        
        //添加动画
        redBall.layer.addAnimation(translation, forKey: translation.keyPath)
        //防止动画还原
        redBall.transform = CGAffineTransformMakeTranslation(100, 0)
  • 组合动画 :JNW实例+JNW实例=JNW组合动画,即分别加入不同的动画即可。
  • 关于渲染的三棵树
    模型树:静态数据,在执行动画时不会改变
    表现树:记录执行动画时的动画数据
    渲染树:屏幕渲染,私有的
  • 自定义警告框
    1、半透明背景层淡入动画
    2、警告框透明度0-1动画,尺寸由1.2变为1
    3、警告框消失,透明度变为0,缩小尺寸
    4、半透明背景层消失

 

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        
        //窗口的代码
        //窗口尺寸
        self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
        //设置窗口背景颜色
        self.window?.backgroundColor = UIColor.whiteColor()
        //激活窗口
        self.window?.makeKeyAndVisible()
        
        self.window?.rootViewController = ViewController()
        
        //灰色的遮挡层
        //遮挡层的frame
        let overlayView = UIView(frame: self.window!.bounds)
        //设置颜色
        overlayView.backgroundColor = UIColor.blackColor()
        //设置透明度,应该为0
        //TODO: 改为0
        overlayView.alpha = 0
        //加入场景
        self.window?.addSubview(overlayView)
        
        //警告框相关代码
        //警告框的宽高
        let alertDimension:CGFloat = 250.0
        //警告框的frame
        let alertViewFrame = CGRectMake(self.window!.bounds.width/2 - alertDimension/2, self.window!.bounds.height / 2 - alertDimension/2, alertDimension, alertDimension)
        //实例化警告框
        let alertView = UIView(frame: alertViewFrame)
        //设置警告框背景
        alertView.backgroundColor = UIColor(patternImage: UIImage(named: "alert_box")!)
        //设置警告框的透明度,应该为0
        //TODO: 改为0
        alertView.alpha = 0
        //设置警告框的初始尺寸为1.2倍
        alertView.transform = CGAffineTransformMakeScale(1.2, 1.2)
        //设置警告框的圆角半径
        alertView.layer.cornerRadius = 10
        
        
        //设置阴影
        //颜色
        alertView.layer.shadowColor = UIColor.blackColor().CGColor
        //阴影偏移
        alertView.layer.shadowOffset = CGSizeMake(0, 0.5)
        //阴影透明度
        alertView.layer.shadowOpacity = 0.3
        //阴影尺寸,跟警告框的圆角半径对应
        alertView.layer.shadowRadius = 10
        
        //将警告框加入当前窗口
        self.window?.addSubview(alertView)
        
        //延时设置
        var minseconds = 1 * Double(NSEC_PER_SEC)
        var dtime = dispatch_time(DISPATCH_TIME_NOW, Int64(minseconds))
        dispatch_after(dtime, dispatch_get_main_queue()) { () -> Void in
            
            //显示动画
            UIView.animateWithDuration(0.3, delay: 0, options: UIViewAnimationOptions.CurveEaseInOut, animations: { () -> Void in
                //背景和警告框显示出来
                overlayView.alpha = 0.3
                alertView.alpha = 1
                }, completion: nil)
            
            //jnw实例
            let scale = JNWSpringAnimation(keyPath: "transform.scale")
            //阻尼值
            scale.damping = 14
            //弹性系数
            scale.stiffness = 440
            //质量
            scale.mass = 1
            //初始值
            scale.fromValue = 1.2
            //结束值
            scale.toValue = 1
            //执行动画
            alertView.layer.addAnimation(scale, forKey: scale.keyPath)
            //更新一下执行完动画后的scale值,防止还原
            alertView.transform = CGAffineTransformMakeScale(1, 1)
        }
        
        minseconds = 3 * Double(NSEC_PER_SEC)
        dtime = dispatch_time(DISPATCH_TIME_NOW, Int64(minseconds))
        dispatch_after(dtime, dispatch_get_main_queue()) { () -> Void in
            //消失动画
            UIView.animateWithDuration(0.15, delay: 0, options: UIViewAnimationOptions.CurveEaseInOut, animations: { () -> Void in
                overlayView.alpha = 0
                alertView.alpha = 0
                }, completion: nil)
            
            //jnw实例,变小
            let scaleOut = JNWSpringAnimation(keyPath: "transform.scale")
            scaleOut.damping = 14
            scaleOut.stiffness = 14
            scaleOut.mass = 1
            scaleOut.fromValue = 1
            scaleOut.toValue = 0.7
            
            alertView.layer.addAnimation(scaleOut, forKey: scaleOut.keyPath)
            alertView.transform = CGAffineTransformMakeScale(0.7, 0.7)
            
            let translation = JNWSpringAnimation(keyPath: "transform.translation.y")
            translation.damping = 14
            translation.stiffness = 14
            translation.mass = 1
            translation.fromValue = self.window!.bounds.size.height/2 - alertDimension/2
            translation.toValue = self.window!.bounds.size.height
            alertView.layer.addAnimation(translation, forKey: translation.keyPath)
        }
        return true
    }

3、Facebook Pop(Facebook Paper)

适用所有的对象。

  • 使用pod引入pop
  • 实例

   

//添加一个红球
        let redBall = UIView(frame: CGRectMake(100, 100, 100, 100))
        redBall.backgroundColor = UIColor.redColor()
        redBall.layer.cornerRadius = 50
        self.view.addSubview(redBall)
        
        //增加pop动画
        //实例化一个pop对象
        let scale = POPSpringAnimation(propertyNamed: kPOPViewScaleXY)
        //fromValue默认为原来的值
        //设置结束值,放大2倍
        scale.toValue = NSValue(CGPoint:CGPointMake(2, 2))
        //设置弹性,振幅之类的属性,值范围0-20
        scale.springBounciness = 20
        //设置震动速度,值越大动画结束速度越快,范围0-20
        scale.springSpeed = 1
        //加入pop动画,forKey,随便取值,唯一即可
        redBall.pop_addAnimation(scale, forKey: "scaleAnimation")

     

//添加一个红球
        let redBall = UIView(frame: CGRectMake(100, 100, 100, 100))
        redBall.backgroundColor = UIColor.redColor()
//        redBall.layer.cornerRadius = 50
        self.view.addSubview(redBall)
        
        //旋转动画
        //x坐标位移动画,PositionX从100->300
        let move = POPSpringAnimation(propertyNamed: kPOPLayerPositionX)
        move.toValue = 300
        move.springBounciness = 20
        move.springSpeed = 5
        redBall.layer.pop_addAnimation(move, forKey: "moveAnimation")
        
        //旋转动画
        let rotation = POPSpringAnimation(propertyNamed: kPOPLayerRotation)
        rotation.toValue = M_PI * 4 //2圈
        rotation.springBounciness = 20
        rotation.springSpeed = 5
        redBall.layer.pop_addAnimation(rotation, forKey: "rotationAnimation")
        
        //背景颜色变化
        let color = POPSpringAnimation(propertyNamed: kPOPViewBackgroundColor)
        color.toValue = UIColor.greenColor()
        color.springBounciness = 20
        color.springSpeed = 5
        redBall.pop_addAnimation(color, forKey: "colorAnimation")