iOS中CAReplicatorLayer的介绍和使用

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)

效果如下

屏幕快照 2018-11-19 下午5.35.25.png

反射效果

使用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)

效果如下

屏幕快照 2018-11-21 下午4.49.13.png

音量柱动画

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

效果如下

2018-11-21 17-36-04.2018-11-21 17_36_18.gif

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

效果如下

2018-11-21 17-53-55.2018-11-21 17_54_05.gif

参考

CAReplicatorLayer

你可能感兴趣的:(iOS中CAReplicatorLayer的介绍和使用)