zoukankan      html  css  js  c++  java
  • 动画分析步骤“三步曲”

    摘要: 本文将实现简单的“登录界面按钮移动效果”,并通过此动画效果介绍动画设计和分析的思路。本文不仅旨在让大家弄清动画效果是如何通过代码来实现的,更重要的是希望大家通过对本文的学习,掌握动画设计和分析的思路。本文选自《iOS动画——核心技术与案例实战》

      首先先来看看动画设计中的三个角色:产品设计师、算法分析师以及伟大的程序员都有哪些职责。
    (1)产品设计师:告诉大家想做一个什么样的动画。
    (2)算法分析师:分析动画的实现原理并设计相应的动画算法。
    (3)程序员:思考如何用代码实现算法。
      在一般中小规模的公司中,开发人员往往都是身兼数职。不仅要编写代码还要参与到算法的设计中去,甚至参与到动画原型的设计中去。所以弄清楚动画设计过程中的不同角色,以及搞清楚动画的分析过程是非常有必要的。

    1 动画分析方法

      下图是我们想要实现的动画效果,那么如何来分析它呢?其实产品设计师在设计动画时,如果能够将动画分解为单帧图像,或者能够较为慢速地展现动画的变化过程,那么对于算法分析师和程序员分析动画的原理,以及设计合适的展现算法起着非常重要的作用。下图描述了登录按钮从左到右逐渐移动的效果,并最后停留在视图层中间位置这一过程。
    【图1】

      这个动画效果非常简单,可以用一句话来描述其实现算法,即图像的水平方向位置坐标和时间呈线性渐变关系。接下来思考如何用代码实现这个效果。按照动画的展示过程,这里将动画分为:动画起始阶段、动画进行阶段和动画结束阶段。

    1.动画起始阶段

      在动画启动的瞬间,希望动画从屏幕可视界面外飞入进来。如下图所示的登录按钮是需要实现的动画起始位置。
    【图2】
      在iOS视图中,左上角为视图的原点(0,0),水平向右为x轴递增方向,竖直向下为y轴递增方向,只有当View视图位于手机屏幕展示坐标系之内,大家才能看到(虚线区域内控件不可见),否则登录按钮是不可见的。所以在动画的起始阶段可以将动画的位置属性设置在界面之外。

    2.动画进行阶段

      经过前面的分析,大家已经了解了这个动画效果的实现算法,即登录按钮的坐标沿水平方向随时间线性变化。如表1.1所示描述了不同时间段登录按钮的坐标变化情况。幸运的是大家不需要手动设计这一过程,甚至不需要手动写线性渐变的方法,因为iOS在UIView的显示层已经帮我们把这个功能集成了。iOS在UIView图层中不仅集成了动画的线性渐变方法,而且动画的加速、减速以及复杂的动画变化时间函数、运动路径函数也已经为大家集成好了,所以只需要学会如何使用这些丰富的API即可,且这个功能只需要几行代码就可以实现。
      表1.1 6S下QQ图标移动效果:QQ图标x、y坐标随时间变化关系表
    图片描述

    3.动画结束阶段

      在动画效果结束之后没有触发新的回调事件,只是更新了当前登录按钮的最后位置,所以图片最终停留在视图层的中间位置。

    2 登录按钮移动动画效果:闭包形式

    首先创建一个单视图工程,创建好之后可以看到下图的工程文件目录结构:
    【图3】
      动画实现的第一阶段:动画起始阶段
      在开始正式添加动画代码之前需要为应用添加一个背景图片。在Main.storyboard中为整个工程添加一个已经准备好的背景图片,背景图片依托在UIImageView上。
    【图4】
      上图为当前工程的Main.storyboard中图层结构,其中View Controller为整个工程的视图控制器,login为UIImageView登录背景图片。下图示是准备好的背景图片,通过下图可以看出,要想实现最初所示的动画效果,只需为整个登录界面添加一个登录按钮即可。
    【图5】
      动画起始阶段代码需要放在什么位置才合适呢?要想弄清楚这个问题先搞清楚ViewController.swift 中几个方法的执行顺序。需要关注以下3个方法。

    viewDidLoad()
    viewWillAppear()
    viewDidAppear()
    

      在应用启动之后,在viewDidLoad中会装载所有的View视图,注意,虽然所有View视图都被装载进来,但是这时所有的View视图并不是可见的。程序接着调用viewWillAppear方法,这是视图在展现之前需要调用的方法。而最后调用viewDidAppear,表明所有的视图已经可见。经过以上分析,大家应该清楚,在动画起始阶段可以将所有的初始化代码放置在viewDidLoad()方法中。具体实现代码如下所示。

    1   var loginButton:UIButton?
    2   override func viewDidLoad() {
    3       super.viewDidLoad()
    4       loginButton = UIButton(frame: CGRect(x:-394,y:230,
                          self.view.frame.width-20*2,height:50))
    5      loginButton!.backgroundColor = UIColor(red: 50/255.0, green: 185/255.0, blue: 170/255.0, alpha: 1.0)
    6       loginButton!.setTitle("登录", for: UIControlState. normal)
    7      self.view.addSubview(loginButton!)
        }
    

      代码第1行创建了一个UIButton登录按钮。第3行重写viewDidLoad方法,表明应用启动之后首先通过调用viewDidload方法加载各种UI组键。第4行设置当前UIButton登录按钮的位置,按钮的x坐标设置在整个界面之外,因此当前Button按钮是不可见的。第5行为登录按钮添加一个淡绿色背景。第6行设置登录按钮Title内容。最后一行将按钮添加到self.view图层上。
      动画实现的第二阶段和第三阶段:动画进行阶段和动画结束阶段
    要想实现应用打开动画即展现的效果,需要在View视图整体展现之前完成动画实现的第二阶段和第三阶段的设置(因为如果视图已经显示了才设置动画效果,那么会有动画不连贯的现象),所以这部分功能只能放置在viewWillAppear方法中。
    这里使用的UIButton按钮和UI控件都是继承UIView类,UIView类中有一个动画方法可以完成我们想要实现的功能:

    open class func animate(withDuration duration: TimeInterval, animations: @escaping () -> Swift.Void)
    

      该方法属于类方法,类名可以直接调用,表明为当前的UIView添加一个动画效果,它的每个参数的含义如下。

    • duration:表明动画执行周期。
    • animations:表明动画执行内容。

    注意,这里animations是一个闭包,使用闭包的方式将动画代码追加进去。在闭包中只需要将动画的结束状态设置完成,那么动画从开始到结束的中间过程,iOS都会自动实现。下面为viewWillAppear()中的动画实现代码。

        override func viewWillAppear(_ animated: Bool) {
            UIView.animate(withDuration: 1, animations: {
              self.loginButton!.frame = CGRect(x:20,
                    y:self.loginButton!.frame.origin.y, 
                     self.loginButton!.frame.width, 
                     height:self.loginButton!.frame.height))
            })
        }
    

      animate方法中,duration表明动画执行周期为1s,动画闭包部分表明登录按钮最终的位置,即最终停留在手机屏幕的中间位置。

    3 登录按钮移动动画效果:方法形式

      除了使用闭包的方法之外,还可以使用另外一种方式实现这个动画效果,即通过commit相关方法的形式来实现。通过修改viewWillAppear()中的内容,可以实现相同的动画效果。下面是动画移动效果的另外一种代码实现方式。

        override func viewWillAppear(animated: Bool) {
    1        UIView.beginAnimations(nil, context: nil)//动画开始
    2        UIView.setAnimationDuration(1)//动画周期设置
    3        loginButton!.frame = CGRect(x:20,
                   y:loginButton!.frame.origin.y,
                   loginButton!.frame.width,
                   height:loginButton!.frame.height)//动画位置设置
    4       UIView.commitAnimations()//动画提交
        }
    

      代码第1行表明动画开始,这里先忽略需要传递的参数,可以先传递两个nil。第2行设置动画执行周期,这里将动画周期设置为1s。第3行将登录按钮设置在屏幕中间位置。代码最后一行将动画效果提交到系统上运行。
      其实无论是第2节的动画实现方法抑或是第3节的动画实现方法,都可以把动画实现的过程总结为下面的3个步骤。
    【图6】
      而第2节和第3节实现动画的唯一区别就是一个使用闭包的形式,而另一个使用beginAnimations和commitAnimations方法的形式启动动画。

    4 UIView视图中常见动画的属性分析

      我们在第2节和第3节主要依靠UIView下的frame属性来实现登录按钮从左到右的进入效果。那么UIView下的其他属性是不是也可以有类似的效果呢?要想回答这个问题,首先需要弄清楚UIView都有哪些常见的属性。

    1.位置属性:frame bounds center

      frame、bounds、center都是描述UIView的位置信息,不同的是frame可以对x坐标、y坐标、width、height四个属性进行操作,frame的x坐标和y坐标相对于父控件的原点来计算,而bounds一般只能对width、height进行操作,它的x、y坐标只相对于自身而言,center描述的是x、y信息,即UIView的中心位置。下面是CGRect、origin、size的代码描述。

    public struct CGRect {
        public var origin: CGPoint
        public var size: CGSize
        public init()
        public init(origin: CGPoint, size: CGSize)
    }
    

      再来看看三者的数据类型。frame是CGRect类型,它是一个结构体,在结构体中包含origin和size两个属性。其中origin描述UIView的x、y坐标起始位置信息,size描述UIView的width、height宽高信息。我们再来看看origin的CGPoint和size的CGSize又是什么。

      CGpoint中包含了UIView的x、y坐标,而CGSize中包含了UIView的Width、Height信息。通过对frame中数据类型的追本溯源,可以得到以下结论:CGRect分别对应x坐标、y坐标、width、height四个属性。这四个属性表明当前UI在它的父控件上的位置,如self.view上。
      通过以上分析可以知道,可以通过x、y坐标修改UIView的移动位置,还可以通过修改width或者height来修改UIView的拉伸、收缩效果。对于bounds属性使用最多的还是width、height属性,center则经常使用x、y坐标属性。

    2.透明度属性:alpha(透明度属性、范围0-1、浮点型)

      UIView的alpha透明度属性也可以用作动画效果。当alpha为0时,表明UIView已经隐藏,当alpha为1时UIView显示。结合这一特征可以通过修改alpha在动画开始、结束时的值,实现UIView的淡入淡出效果。

    3.Layer属性:圆角渐变、边框颜色、阴影、3D等高级动画效果

      UIView是视图显示的容器,负责内容显示和事件响应。每个UIView都有一个Layer图层,在这个图层中承载的是视图的内容,所以结合Layer可以实现很多高级的动画效果。当然除了这些之外,UIView还有很多其他属性,在后面的章节中会为大家一一呈现。

    5 小结

      通过对本文的学习,相信大家基本上掌握了动画分析的基本步骤,在这里总结一下动画实现的三个步骤:
    (1)设置视图的动画初始状态。
    (2)添加视图的动画相应属性。
    (3)设置视图的动画最终状态。
      在通过帧分解等方法了解了动画的实现原理之后,通过这三个步骤可以很方便地实现各种动画效果。本章结合登录按钮移动效果为大家展示了动画分析和实现的全过程,并通过代码详细介绍了通过闭包方式,以及beginAnimations和commitAnimations方法的形式实现动画。
      对于UIView中常见的动画属性,结合UIView对视图的位置、透明度、几何形状给大家做了简要的分析,在后面的章节中会结合具体的代码,为大家呈现缤纷多彩的动画效果。
      本文选自《iOS动画——核心技术与案例实战》,点此链接可在博文视点官网查看。
                          图片描述
      想及时获得更多精彩文章,可在微信中搜索“博文视点”或者扫描下方二维码并关注。
                           图片描述

  • 相关阅读:
    爬取校园新闻首页的新闻的详情,使用正则表达式,函数抽离
    网络爬虫基础练习
    Mysql 使用 select into outfile
    Mysql 使用CMD 登陆
    使用Clean() 去掉由函数自动生成的字符串中的双引号
    Get Resultset from Oracle Stored procedure
    获取引用某个主键的所有外键的表
    Entity Framework 丢失数据链接的绑定,在已绑好的EDMX中提示“Choose Your Data Connection”
    添加MySql Metat Database 信息
    at System.Data.EntityClient.EntityConnection.GetFactory(String providerString)
  • 原文地址:https://www.cnblogs.com/broadview/p/6296388.html
Copyright © 2011-2022 走看看