close
当前位置: 物联网在线 > 技术文库 > ios >

神奇的CAReplicatorLayer

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

效果图如下:

神奇的CAReplicatorLayer

镜像层.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; }

流程如上,效果图如下:

神奇的CAReplicatorLayer

loading......

来自:https://github.com/China131/JHLoadingForHJ
 

https://github.com/China131/JHLoadingForHJ


(责任编辑:ioter)

用户喜欢...

兼具实力与颜值的虚拟仪表盘有多神奇

汽车仪表盘从最初的功能形态发展至今,已经不再是一个提供转速、车速的简单元件,更多的是车载信息的集成和科...


深度 | 神奇的神经机器翻译:从发展脉络到未来前景

机器翻译(MT)是借机器之力「自动地将一种自然语言文本(源语言)翻译成另一种自然语言文本(目标语言)」。使用机器做翻译的思想最早由 Warren Weaver 于 1949 年提出。在很长一段时间里...


总是睡不好吗?这款神奇的头带 Dreem 可以帮助你

你也是失眠、浅眠一族吗?还是睡前 3C 产品的蓝光干扰你的睡眠质量呢?这款神奇的睡眠头带 Dreem 或许可以帮助你!...


神奇!能这朵花能用意念控制

隔空移物、用意念操控别的物体是一切期望特异功能人的愿望,可是这个愿望要完成了。 Neuroflowers上个月初首次在旧金山露脸,它带有一个ECG(心电图监视器)和一个EEG(脑电波的接收器)...


【原创】Marvell如何在一年内完成了神奇逆转?

作者:电子创新网 张国斌 一年前,Marvell 遭遇很大的危机--CEO和总裁双双离职,公司股票低迷,员工士气低落,华尔街的分析师们则连篇累牍地鼓噪将公司卖掉,2016年6月21日,半导体老将M...


医疗传感器愈来愈神奇,未来你将吞数字药丸、被植入芯片、、

从 IT 到医疗,传感器的应用高速进展,电影里的异想世界成为现实,不过是早晚的事。 本文分享 3 个医疗传感器应用...


这个神奇按钮能把你周围世界全变成智能设备

(编译:多多)虽然智能手机和可穿戴设备这样的产品功能已经变得越来越强大,甚至可以控制啤酒机和家里的水龙头,但是毕竟我们生活中接触大的大部分物品还是非常普通。如果能够将我...


Unity制作神奇的粒子海洋!

看到这个效果我就震惊了。首先,这个看起来超神奇,其次,它在并不是很高端的PC浏览器上也能流畅地运行。所以一眼就立刻深深喜欢上了它以及相关的三个.js库文件,想马上使用unity3D来实...


神奇教科书 超赞《幻宠大陆》手游萌宠体系大全

千年前,神明为冷清的大陆创造了生机,孕育生灵万物,将自己的自然之力赋予它们,这些拥有自然之力的神之宠儿...


实现神奇AR和VR体验,且看PowerVR和Zappar的强强联合

若论增强现实(AR)的应用效果,且看今夏《口袋妖怪Go》的成功便可知一二。Zappar是英国一家做增强现实相关产品的公司,窥得先机,为诸多品牌如愤怒的小鸟、华纳兄弟、可口可乐等创建了增...