zoukankan      html  css  js  c++  java
  • 神奇的CAReplicatorLayer

    代码地址如下:
    http://www.demodashi.com/demo/11702.html

    文档描述:

    The CAReplicatorLayer class creates a specified number of copies of its sublayers (the source layer), each copy potentially having geometric, temporal and color transformations applied to it.

    简介

    • 支持系统:>=iOS3.0。
    • 文档释义:CAReplicatorLayer类可用来从layer源高效复制多个实体对象,每个实体对象都可以拥有几何形状、颜色、时间层次上的不同转换。
    • 实际应用: 加载动画、镜像layer的生成。

    使用示例1:实现一个镜像反射效果

    1.创建一个模板层

      /*        创建一个模板层 CAReplicatorLayer会按照一定的规则“克隆”这个模板         */
      CAShapeLayer *shape = [CAShapeLayer layer];
      shape.frame = CGRectMake(0, 0, 80, 80);
      /*        绘制模板的形状         */
      shape.path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 80, 80)].CGPath;
      /*        模板的填充颜色         */
      shape.fillColor = [UIColor redColor].CGColor;
      shape.opacity = 0.0;
      /*        创建所有的子层的动画组(也可以是单个动画)         */
      CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
      /*        动画组元素         */
      animationGroup.animations = @[[self alphaAnimation],[self scaleAnimation]];
      /*        动画执行时间         */
      animationGroup.duration = 4.0;
      animationGroup.autoreverses = NO;
      animationGroup.repeatCount = HUGE;
      /*        给模板层添加动画 实质上也是给每个CAReplicatorLayer子层添加动画         */
      [shape addAnimation:animationGroup forKey:@"animationGroup"];
      /*        创建CAReplicatorLayer对象         */
      CAReplicatorLayer *replicatorLayer = [CAReplicatorLayer layer];
      replicatorLayer.frame = self.containerView.bounds;
      /*        设置每个元素的添加间隔时间         */
      replicatorLayer.instanceDelay = 0.5;
      /*        设置每元素个数         */
      replicatorLayer.instanceCount = 8;
      /*        给CAReplicatorLayer对象的子层添加转换规则 这里决定了子层的布局         */
      replicatorLayerY.instanceTransform = CATransform3DTranslate(CATransform3DIdentity, 0, radius+between, 0);
      /*        添加子层         */
      [replicatorLayer addSublayer:shape];
    

    Note:在这里,大家可以根据需要添加不同的动画元素或者不添加任何动画,该用法多用于实现加载提示视图的动画制作。

    2.实现某个视图的反射效果

    我们首先继承UIView创建一个子类,在子类的+(Class)layerClass方法中设置当前视图对象的layer为CAReplicatorLayer对象:

      + (Class)layerClass{
       return [CAReplicatorLayer class];
      }
    

    然后在创建该子类的对象时对self.layer进行设置相关参数:

    - (void)setup{
    /*        获取当前的layer 实际上为CAReplicatorLayer对象         */
    CAReplicatorLayer *layer = (CAReplicatorLayer *)self.layer;
    layer.instanceCount = 2;
    layer.anchorPoint = CGPointMake(0.5, 0.5);
    
    /*        创建3D转换效果         */
    CATransform3D transform = CATransform3DIdentity;
    CGFloat verticaloffset = self.bounds.size.height  ;
    transform = CATransform3DTranslate(transform, 0, verticaloffset, 0);
    
    /*        设置Y轴镜面反射         */
    transform = CATransform3DScale(transform, 1, -1, 0);
    transform = CATransform3DRotate(transform, -M_PI / 4, 1, 0, 0);
    layer.instanceTransform  = transform;
    /*        镜面的透明度 越低显示越清晰 因为是镜面效果         */
    layer.instanceAlphaOffset = -0.1;
    }
    

    效果图如下:

    镜像层.png

    示例2:CAReplicatorLayer作为核心技术实现加载动画。

    1.首先,创建一个UIView的子类,并暴露相关方法:

    @interface JHHJView : UIView
    /*        显示加载动画 并添加到父视图上         */
    + (void)showLoadingOnView:(UIView *)superView Type:(JHHJViewType)type;
    /*        显示动画 并添加在主窗口上         */
    + (void)showLoadingOnTheKeyWindowWithType:(JHHJViewType)type;
    /*        停止动画         */
    + (void)hideLoading;
    /*        设置动画背景色(全屏背景色)         */
    + (void)backgroudColor:(UIColor *)color;
    /*        设置中心视图的动画背景颜色 默认透明色         */
    + (void)centerBGViewBackgroudColor:(UIColor *)color;
    

    2.并且声明了一个枚举类型:该枚举类型代表着加载动画类型。

    typedef  NS_ENUM(NSInteger,JHHJViewType){
    /**
     *  线性动画
     */
    JHHJViewTypeSingleLine = 0,
    
    /**
     *  方形点动画
     */
    JHHJViewTypeSquare = 1,
    
    /**
     *  三角形运动动画
     */
    JHHJViewTypeTriangleTranslate = 2,
    
    /**
     *  原型视图裁剪动画
     */
    JHHJViewTypeClip
    };
    

    3.在.m文件中,该类拥有的成员变量如下:

    @interface JHHJView ()
    //中心背景视图
    @property (nonatomic,strong)JHHJCenterBGView *centerBGView;
    //计时器
    @property (nonatomic,strong)NSTimer * clipTimer;
    //层数组
    @property (nonatomic,strong)NSMutableArray * clipLayerArr;
    //计时器计量数
    @property (nonatomic,assign) long long currentTimerIndex;
    //背景层
    @property (nonatomic,strong) CAShapeLayer *bgLayer;
    @end
    

    4.然后,设置以单例的方式创建该类的对象:

    /**
     *  对象单例化
    *
     *  @return 单例对象
    */
    + (JHHJView *)shareInstanceJHHJView{
    static JHHJView * instance = nil;
    if (!instance) {
        instance                     = [[JHHJView alloc] initWithFrame:[UIScreen mainScreen].bounds];
        instance.centerBGView        = [[JHHJCenterBGView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
        instance.centerBGView.center = CGPointMake(K_IOS_WIDTH / 2, K_IOS_HEIGHT/2);
        [instance addSubview:instance.centerBGView];
    }
    return instance;
    }
    

    5.动画的实现如下:

    /**
     *  展示动画视图 并添加到依赖视图上
     *
    *  @param superView 依赖的父视图
    *  @param type      动画样式
    */
    + (void)showLoadingOnView:(UIView *)superView Type:(JHHJViewType)type{
    /*        在显示前  先从父视图移除当前动画视图         */
    JHHJView *instance = [[self class] shareInstanceJHHJView];
    [[self class] hideLoading];
    /*        显示前 先将动画图层从中心视图上移除         */
    for (CALayer *layer in instance.centerBGView.layer.sublayers) {
        [layer removeFromSuperlayer];
    }
    /*        按照type初始化动画         */
    switch (type) {
        case JHHJViewTypeSingleLine:
        {
            CALayer *layer = [instance lineAnimation];
            layer.position = CGPointMake(CGRectGetWidth(instance.centerBGView.frame)/2 - 25, CGRectGetHeight(instance.centerBGView.frame)/2);
            [instance.centerBGView.layer addSublayer:layer];
        }break;
            
        case JHHJViewTypeSquare:
        {
            CALayer *layer = [[self class] qurareAnimation];
            layer.position = CGPointMake(CGRectGetWidth(instance.centerBGView.frame)/2, CGRectGetHeight(instance.centerBGView.frame)/2);
            [instance.centerBGView.layer addSublayer:layer];
        }break;
        case JHHJViewTypeTriangleTranslate:
        {
            CALayer *layer = [[self class] triangleAnimation];
            layer.position = CGPointMake(CGRectGetWidth(instance.centerBGView.frame)/2 - 18, CGRectGetHeight(instance.centerBGView.frame)/2 - 15);
            [instance.centerBGView.layer addSublayer:layer];
        }break;
        case JHHJViewTypeClip:
        {
            
            CALayer *layer = [[self class] clipAnimation];
            layer.position = CGPointMake(CGRectGetWidth(instance.centerBGView.frame)/2 , CGRectGetHeight(instance.centerBGView.frame)/2 - 15);
            [instance.centerBGView.layer addSublayer:layer];
            
        }break;
        default:
            break;
    }
    [superView addSubview:instance];
    }
    

    6.下面来具体实现其中一个动画,以三角形旋转动画为例:

    /**
    *  三角形运动动画
     *
    *  @return 动画实例对象
     */
    + (CALayer *)triangleAnimation{
    /*        基本间距确定及模板层的创建         */
    CGFloat radius                     = 50/4.0;
    CGFloat transX                     = 50 - radius;
    CAShapeLayer *shape                = [CAShapeLayer layer];
    shape.frame                        = CGRectMake(0, 0, radius, radius);
    shape.path                         = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, radius, radius)].CGPath;
    shape.strokeColor                  = [UIColor redColor].CGColor;
    shape.fillColor                    = [UIColor redColor].CGColor;
    shape.lineWidth                    = 1;
    [shape addAnimation:[JHHJAnimation rotateAnimation] forKey:@"rotateAnimation"];
    
    /*        创建克隆层         */
    CAReplicatorLayer *replicatorLayer = [CAReplicatorLayer layer];
    replicatorLayer.frame              = CGRectMake(0, 0, radius, radius);
    replicatorLayer.instanceDelay      = 0.0;
    replicatorLayer.instanceCount      = 3;
    CATransform3D trans3D              = CATransform3DIdentity;
    trans3D                            = CATransform3DTranslate(trans3D, transX, 0, 0);
    trans3D                            = CATransform3DRotate(trans3D, 120.0*M_PI/180.0, 0.0, 0.0, 1.0);
    replicatorLayer.instanceTransform  = trans3D;
    [replicatorLayer addSublayer:shape];
    return replicatorLayer;
    }
    

    流程如上,效果图如下:
    loading......

    项目文件截图

    神奇的CAReplicatorLayer

    代码地址如下:
    http://www.demodashi.com/demo/11702.html

    注:本文著作权归作者,由demo大师代发,拒绝转载,转载需要作者授权

  • 相关阅读:
    Android系统匿名共享内存(Anonymous Shared Memory)C++调用接口分析
    AntRename的使用 文件重命名
    Android应用程序键盘(Keyboard)消息处理机制分析
    xp 和 win7 下双击直接运行.jar文件
    Android录制声音(一)Recorder
    Android应用程序线程消息循环模型分析
    Android4.0升级新特性
    关于返回按钮的重载,即返回按钮的退出设置
    Informix IDS 11零碎管理(918考试)认证指南,第2部分零碎运动监督(7)
    Informix IDS 11细碎解决(918查验)认证指南,第1局部IDS装置和设置(2)
  • 原文地址:https://www.cnblogs.com/demodashi/p/8509599.html
Copyright © 2011-2022 走看看