代码地址如下:
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;
}

效果图如下:

示例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;
}

流程如上,效果图如下:

项目文件截图

神奇的CAReplicatorLayer

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

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

神奇的CAReplicatorLayer相关推荐

  1. CAReplicatorLayer复制Layer和动画, 实现神奇的效果

    今天我们看下CAReplicatorLayer, 官方的解释是一个高效处理复制图层的中间层.他能复制图层的所有属性,包括动画. 一样我们先看下头文件 @interface CAReplicatorLa ...

  2. 一段神奇的c代码错误分析

    源代码 #include <stdio.h>int main(int argc, char* argv[]) {int i = 0;int arr[3] = {0};printf(&quo ...

  3. python deque双端队列的神奇用法

    python中的deque双端队列,类似list的任意一端都可实现较快的add和pop操作 from collections import dequed=deque(maxlen=20) for i ...

  4. 几行代码实现神奇移动的过渡动画

    1.效果如图: 2.实现: 假设需求为如上图,点击ViewController01后,ViewController01上的两张图片,移动到ViewContoller02中,其实两个ViewContro ...

  5. Hudson神奇的环境变量

    Hudson神奇的环境变量 http://blog.sina.com.cn/s/blog_798f21a00100z6zw.html 转载于:https://blog.51cto.com/mylove ...

  6. 神奇的输入 while(cin....)如何在遇见换行之后进入下一层循环读入

    1 cin>>m>>n; 2 for(int i=1;i<=m;i++) { 4 int x=0; 5 char ch=' '; 6 while(ch!=10) //在遇 ...

  7. 【NOIP2015提高组Day1】 神奇的幻方

    [问题描述] 幻方是一种很神奇的 N*N矩阵:它由数字1,2,3, - - ,N*N 构成,且每行.每列及两条对角线上的数字之和都相同. 当N为奇数时,我们可以通过以下方法构建一个幻方: 首先将1写在 ...

  8. 图片提取文字功能很神奇?Java几行代码搞定它!

    欢迎关注方志朋的博客,回复"666"获面试宝典 来源:blog.csdn.net/weixin_44671737/ article/details/110000864 摘要 近日浏 ...

  9. CVPR 2021:记一次神奇的 Rebuttal 经历

    点击上方"视学算法",选择加"星标"或"置顶" 重磅干货,第一时间送达 作者丨信息门下遛狗@知乎(已授权) 来源丨https://zhuan ...

最新文章

  1. JAVA Functions in XI(转)
  2. 掉一根头发,搞定二叉排序(搜索)树
  3. NullPointerException: null 报错
  4. oralce或sql中join的用法
  5. mvc怎么单独引用css文件,关于asp.net mvc:如何在剃刀视图中引用.css文件?
  6. 如何利用 Webshell 诊断 EDAS Serverless 应用
  7. 鼠标移动响应php程序,jQuery实现的响应鼠标移动方向插件用法示例【附源码下载】...
  8. 【异常】INFO: TopologyManager: EndpointListener changed ...
  9. Java基础学习总结(139)——Java8 Stream之Stream接口入门简介
  10. linux 命令快捷,Linux常见命令快捷方式(示例代码)
  11. boost 静态库命名规则
  12. java 反射如何给属性赋值_关于Java属性反射的异常问题
  13. 使用 ReportLab 绘制 PDF
  14. java代码取出EXCEL表数据并画折线图
  15. python导入随机函数库_Python随机函数库random的使用方法详解
  16. 期货结算价是怎样产生的?
  17. MySql中用sql语句实现按汉字首字母排序
  18. 【代码审计】--- php代码审计方法
  19. 【自然语言处理】【大模型】BLOOM:一个176B参数且可开放获取的多语言模型
  20. 谷歌浏览器不能使用opener属性的问题和解决

热门文章

  1. STN32F103系列IO脚引脚分布
  2. flash 4K扇区写入函数
  3. Makefile语法总结
  4. 网络协议栈深入分析(四)--套接字内核初始化和创建过程
  5. 路由表(FIB)详解
  6. 内核中的UDP socket流程(6)——sendto
  7. linux input子系统分析--主要函数
  8. 【AD】Altium designer pcb 交叉选择模式
  9. java中文本框如何表示为空值_去jsp页面中文本框有NULL值的代码
  10. web端 微软 RDLC 报表插件 宽大于高 横向打印失效 解决方案