CAReplicatorLayer
CAReplicatorLayer的目的是为了高效生成许多相似的图层。它会绘制一个或多个图层的子图层,并在每个复制体上应用不同的变换,复制的出来的layer和原来的子layer拥有相同的动效。它能够重建包括自己在内的n个copies,这些copies是原layer中的所有sublayers,并且任何对原layer的sublayers设置的transform是可以积累的(accumulative)
CAReplicatorLayer属性
- 设置实例显示属性(Setting Instance Display Properties)
/* The number of copies to create, including the source object.
* Default value is one (i.e. no extra copies). Animatable. */
// 创建副本的数量,包括原对象,默认有一个,可动画属性
open var instanceCount: Int
/* The temporal delay between replicated copies. Defaults to zero.
* Animatable. */
// 显示延时
open var instanceDelay: CFTimeInterval
/* The matrix applied to instance k-1 to produce instance k. The matrix
* is applied relative to the center of the replicator layer, i.e. the
* superlayer of each replicated sublayer. Defaults to the identity
* matrix. Animatable. */
// 对实例进行变换
open var instanceTransform: CATransform3D
- 修改实例几何(Modifying Instance Layer Geometry)
/* Defines whether this layer flattens its sublayers into its plane or
* not (i.e. whether it's treated similarly to a transform layer or
* not). Defaults to NO. If YES, the standard restrictions apply (see
* CATransformLayer.h). */
//
open var preservesDepth: Bool
- 访问实例颜色值(Accessing Instance Color Values)
/* The color to multiply the first object by (the source object). Defaults
* to opaque white. Animatable. */
open var instanceColor: CGColor?
/* The color components added to the color of instance k-1 to produce
* the modulation color of instance k. Defaults to the clear color (no
* change). Animatable. */
open var instanceRedOffset: Float
open var instanceGreenOffset: Float
open var instanceBlueOffset: Float
open var instanceAlphaOffset: Float
实战
创建5个渐变的正方形
// 创建replicatorLayer
let replicatorLayer = CAReplicatorLayer()
replicatorLayer.frame = CGRect(x: 10, y: 100, width: 75, height: 75)
// 创建子layer
let redSquare = CALayer()
redSquare.backgroundColor = UIColor.white.cgColor
redSquare.frame = CGRect(x: 0, y: 0, width: 75, height: 75)
// 设置实例的个数
let instanceCount = 5
replicatorLayer.instanceCount = instanceCount
// 沿着x轴移动80,80是正方形宽度75和间距5之和
replicatorLayer.instanceTransform = CATransform3DMakeTranslation(80, 0, 0)
// 设置颜色
let offsetStep = -1 / Float(instanceCount)
replicatorLayer.instanceBlueOffset = offsetStep
replicatorLayer.instanceGreenOffset = offsetStep
replicatorLayer.addSublayer(redSquare)
view.layer.addSublayer(replicatorLayer)
效果如下
反射效果
使用CAReplicatorLayer并应用一个负比例变换于一个复制图层,你就可以创建指定视图(或整个视图层次)内容的镜像图片,这样就创建了一个实时的反射效果。
// 创建replicatorLayer
let replicatorLayer = CAReplicatorLayer()
replicatorLayer.frame = CGRect(x: 100, y: 100, width: 100, height: 100)
//注意:是包括自己在内总共为2个对象
replicatorLayer.instanceCount = 2
// 创建transform
var transform = CATransform3DIdentity
let verticalOffset: CGFloat = replicatorLayer.bounds.height
// 沿y轴移动verticalOffset高度
transform = CATransform3DTranslate(transform, 0, verticalOffset + 2, 0)
// 沿着z轴旋转180度
transform = CATransform3DRotate(transform, CGFloat.pi, 0, 0, 1)
// 使用transform
replicatorLayer.instanceTransform = transform
replicatorLayer.instanceAlphaOffset = -0.6
// 添加子layer
let subLayer = CALayer()
subLayer.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
subLayer.contents = UIImage(named: "4")?.cgImage
replicatorLayer.addSublayer(subLayer)
效果如下
音量柱动画
func musicAnimation() {
// 创建replicatorLayer
let replicatorLayer = CAReplicatorLayer()
let height: CGFloat = 230
replicatorLayer.frame = CGRect(x: 100, y: 100, width: height, height: height)
replicatorLayer.backgroundColor = UIColor.gray.cgColor
view.layer.addSublayer(replicatorLayer)
// 创建音量条
let volumeLayer = CALayer()
volumeLayer.backgroundColor = UIColor.cyan.cgColor
let volumeWidth: CGFloat = 30
volumeLayer.bounds = CGRect(x: 0, y: 0, width: volumeWidth, height: 100);
volumeLayer.anchorPoint = CGPoint(x: 0, y: 1)
volumeLayer.position = CGPoint(x: 0, y: height)
view.layer.addSublayer(volumeLayer)
// 对音量条添加动画
let animation = CABasicAnimation(keyPath: "transform.scale.y")
animation.toValue = 0
animation.duration = 1.0
animation.repeatCount = Float.infinity
animation.autoreverses = true
volumeLayer.add(animation, forKey: nil)
replicatorLayer.addSublayer(volumeLayer)
// 设置音量条个数
replicatorLayer.instanceCount = 6
// 设置延时
replicatorLayer.instanceDelay = 0.35
// 设置透明度递减
replicatorLayer.instanceAlphaOffset = -0.15
// 对每个音量震动条移动40
replicatorLayer.instanceTransform = CATransform3DMakeTranslation(volumeWidth + 10, 0, 0)
}
效果如下
func dotLoading() {
let replicatorLayer = CAReplicatorLayer()
replicatorLayer.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
replicatorLayer.position = view.center
view.layer.addSublayer(replicatorLayer)
// 添加小圆点
let dotLayer = CALayer()
dotLayer.bounds = CGRect(x: 0, y: 0, width: 10, height: 10)
dotLayer.position = CGPoint(x: 50, y: 20)
dotLayer.backgroundColor = UIColor(red: 0.1, green: 0.1, blue: 0.1, alpha: 0.6).cgColor
dotLayer.cornerRadius = 5;
dotLayer.masksToBounds = true
replicatorLayer.addSublayer(dotLayer)
// 添加缩放动画
let animation = CABasicAnimation(keyPath: "transform.scale")
animation.duration = 1
animation.fromValue = 1
animation.toValue = 0.1
animation.repeatCount = Float.infinity
dotLayer.add(animation, forKey: nil)
// 设置个数
let count = 12
replicatorLayer.instanceCount = count
// 每次旋转的角度等于 2π / 12
replicatorLayer.instanceTransform = CATransform3DMakeRotation((2 * CGFloat.pi) / CGFloat(count) , 0, 0, 1)
// 添加延迟
replicatorLayer.instanceDelay = CFTimeInterval(1.0 / CGFloat(count))
// 解决最开始旋转衔接效果
dotLayer.transform = CATransform3DMakeScale(0.01, 0.01, 0.01);
}
效果如下
参考
CAReplicatorLayer