iOS动画编程-进阶
iOS动画编程-进阶
hejunbinlan 发表于2年前
iOS动画编程-进阶
  • 发表于 2年前
  • 阅读 412
  • 收藏 7
  • 点赞 0
  • 评论 0

腾讯云 新注册用户 域名抢购1元起>>>   

摘要: iOS动画编程-进阶

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


    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))

            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")

更多POP的实例参考网址:https://github.com/facebook/pop

共有 人打赏支持
粉丝 38
博文 528
码字总数 21018
×
hejunbinlan
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: