CoreAnimation 之CAReplicatorLayer
CAReplicatorLayer:
主要作用有以下两个:
- CAReplicatorLayer的目的是为了高效生成许多相似的图层,它会绘制一个或多个图层的子图层 并在每个复制体上应用不同的变换
- 使用CAReplicatorLayer的其中一个实际应用:反射 使用CAReplicatorLayer并应用一个负比例变换于一个复制图层 你就可以创建指定视图内容的镜像图片 这样就创建了一个实时的反射效果
首先看第一个的代码示例:
/* 创建一个模板层 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];
在这里,大家可以根据需要添加不同的动画元素或者不添加任何动画,该用法多用于实现加载提示视图的动画制作。
第二个用法,实现某个视图的反射效果:
我们首先继承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; }
效果图如下