zoukankan      html  css  js  c++  java
  • iOS动画

    UIView动画(过渡效果)的学习笔记

    http://www.cnblogs.com/lovecode/archive/2011/11/05/2237077.html

    谈谈iOS Animation

    http://geeklu.com/2012/09/animation-in-ios/

    iOS开发系列--让你的应用“动”起来

    ********************************************

    一,设计复杂的iOS动画效果的一些设计原理

    1、制定统一的动画接口
         1)统一动画接口是为了实现后续复杂的动画组合;
      2)统一动画接口对于后续的代码维护极为方便;
      3) 统一动画接口需要优先考虑里氏代换原则;
    2、动画中的高内聚低耦合原理
        1)不要把实现动画的细节暴露在外  
        2)设计动画类尽量要符合单一职能原则,以便后续方便组合成复杂的动画效果

         如果一个类承担的职能过多,就等于把这些职能耦合在一起,一个职能的变化可能会削弱或者抑制其他职能的能力,这种耦合会导致脆弱的设计,当发生变化时,设计会遭到意想不到的破坏。如果想要避免这种现象发生,就要尽可能的遵守单一职能原则。

    3、设计动画函数的注意事项
       1)动画方法的命名统一
       2)预留非动画情形的设计
       3)用百分比来表示动画的执行程度 
       4)懒加载的使用 :节省系统开销
    // 显示动画
    - (void)showWithDuration:(CGFloat)duration animated:(BOOL)animated;
    
    // 隐藏动画
    - (void)hideWithDuration:(CGFloat)duration animated:(BOOL)animated;
    
    // 创建view
    - (void)buildView;
    
    // 动画百分比(手动设置动画的程度)
    - (void)percent:(CGFloat)percent;
    4、用里氏代换原则来处理动画类的继承问题
    1)里氏代换原则的基本原理:
          任何基类可以出现的地方,子类一定可以出现
    2)设计中要确保父类可以直接调用子类的方法
    3)将父类设计成虚类
    5、动画中的模块化设计

    二 、使用maskView设计动画

    首先是确定maskview和view的重叠范围 ,不重叠部分不显示;其次是透明度,透明部分不显示;

      1、maskView(maskLayer)基本原理

        1)蒙板的基本原理

           mask——蒙板,是将不同灰度色值转化为不同的透明度,并作用到它所在的图层,使图层不同部位透明度产生相应的变化。黑色为完全透明,白色为完全不透明。

    蒙版:
    ①它是一种特殊的选区,但它的目的并不是对选区进行操作,相反,而是要保护选区的不被操作。同时,不处于蒙板范围的地方则可以进行编辑与处理。 
    ②蒙板虽然是种选区,但它跟常规的选区颇为不同。常规的选区表现了一种操作趋向,即将对所选区域进行处理;而蒙板却相反,它是对所选区域进行保护,让其免于操作,而对非掩盖的地方应用操作

        2)png图片透明像素的原理  :  只有png图片才有透明遮罩效果,jpg的不行。

        3)maskView(maskLayer)可类比于多张png图片的叠加遮罩,原理类似

        4)maskView是iOS8以上才有的,如果要考虑兼容低版本,用maskLayer替换

        // 底图
        self.baseImageView       = [[UIImageView alloc] initWithFrame:CGRectMake(20, 20, width, width)];
        self.baseImageView.image = [UIImage imageNamed:@"base"];
        [self.view addSubview:self.baseImageView];
        
        // mask
        self.maskImageView       = [[UIImageView alloc] initWithFrame:CGRectMake(20, 20 + width + 20, width, width)];
        self.maskImageView.image = [UIImage imageNamed:@"mask"];
        [self.view addSubview:self.maskImageView];
        
        // 使用maskView的情况
        self.addImageView       = [[UIImageView alloc] initWithFrame:CGRectMake(20, 20 + (width + 20) * 2, width, width)];
        [self.view addSubview:self.addImageView];
        self.addImageView.image = [UIImage imageNamed:@"base"];
        UIImageView *mask          = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, width, width)];
        mask.image                 = [UIImage imageNamed:@"mask"];
        
        // maskView并不能用addSubview来添加遮罩,这点千万注意
        self.addImageView.maskView = mask;

      

         2、maskView配合CAGradientLayer的使用

        1)用CAGradientLayer直接产生带透明像素通道的layer
        2)用maskView直接加载带CAGradientLayer的view
        3)可以通过对CAGradientLayer进行动画的操作实现动画效果
     
        // 加载图片
        UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(20, 20, 200, 200)];
        imageView.image        = [UIImage imageNamed:@"base"];
        [self.view addSubview:imageView];
        
        // 创建出CAGradientLayer
        CAGradientLayer *gradientLayer = [CAGradientLayer layer];
        gradientLayer.frame            = imageView.bounds;
        gradientLayer.colors           = @[(__bridge id)[UIColor clearColor].CGColor,
                                           (__bridge id)[UIColor blackColor].CGColor,
                                           (__bridge id)[UIColor clearColor].CGColor];
        gradientLayer.locations        = @[@(0.25), @(0.5), @(0.75)];
        gradientLayer.startPoint       = CGPointMake(0, 0);
        gradientLayer.endPoint         = CGPointMake(1, 0);
        
        // 容器view --> 用于加载创建出的CAGradientLayer
        UIView *containerView = [[UIView alloc] initWithFrame:imageView.bounds];
        [containerView.layer addSublayer:gradientLayer];
    
        // 设定maskView
        imageView.maskView  = containerView;
    
        CGRect frame        = containerView.frame;
        frame.origin.x     -= 200;
        
        // 重新赋值
        containerView.frame = frame;
        
        // 给maskView做动画效果
        [UIView animateWithDuration:3.f animations:^{
            // 改变位移
            CGRect frame        = containerView.frame;
            frame.origin.x     += 400;
            
            // 重新赋值
            containerView.frame = frame;
        }];

    效果如下图:

       

      3、maskView配合带alpha通道图片的使用
            阿尔法通道是一个8位的灰度通道,该通道用256级灰度来记录图像中的透明度信息,定义透明、不透明和半透明区域,其中黑表示透明,白表示不透明,灰表示半透明。
            阿尔法通道(Alpha Channel)是指一张图片的透明和半透明度。
     
        1)直接使用带alpha通道的png图片比用CAGradientLayer的方式更加高效
        2)可以使用技巧在maskView上添加多张图片
        3)在maskView中做简单的动画
     
      4、设计文本横向渐变消失的控件
            1)接口的设计
        2)封装CAGradientLayer用以提供mask遮罩
        3)动画样式的分析与设计

    三,用缓动函数模拟物理动画

      1、‣缓动函数简介

        1)、缓动函数的动画效果是建立在CALayer层级的关键帧动画基础之上

        2)、缓动函数是一系列模拟物理效果(如抛物线)方程式的统称,用以计算给定两点之间的插值

        3)、两点之间插的值越多,效果越好,但是会耗费更多的性能

        4)、只有理解了缓动函数的原理才有可能写出自己想要的效果

      2、缓动函数与关键帧动画的联系

        1)、关键帧动画需要提供很多的帧来完善动画效果

        2)、关键帧动画的帧可以通过一定的数学计算来提供需要的帧数

        3)、关键帧动画只需要提供起始点,结束点,就可以通过缓动函数来计算中间“缺失”的帧  

        4)、缓动函数可以指定计算出多少帧

        5)、帧数越多,动画越流畅,但同时耗费更多的GPU性能

      3、用缓动函数模拟弹簧效果

        1)、使用easeOutElastic函数来创建弹簧效果

        2)、将easeOutElastic创建出来的帧数组添加到关键帧动画中

        3)、弹簧效果用途

      4、用缓动函数模拟碰撞效果

        1)、使用easeOutBounce函数来创建弹簧效果

        2)、将easeOutBounce创建出来的帧数组添加到关键帧动画中

        3)、碰撞效果用途

      5、用缓动函数模拟衰减效果

        1)、使用easeOutCubic函数来创建弹簧效果

        2)、将easeOutCubic创建出来的帧数组添加到关键帧动画中

        3)、衰减效果用途

  • 相关阅读:
    Flutter-路由
    写一个底部Tabs导航动态组件
    实例:Flutter布局01
    HTTP报文
    HTML文本的各种属性
    HTML必要简介和基础
    MySQL8.0.23安装超详细傻瓜式
    从一个HTTP请求来研究网络分层原理
    MySQL的增删改查
    MySQL常用数据类型有哪些?
  • 原文地址:https://www.cnblogs.com/developer-qin/p/4537894.html
Copyright © 2011-2022 走看看