iOS CALayer - kgleong/software-engineering GitHub Wiki

CALayer

Gradient Layer

class MyView: UIView {
    override func draw(_ rect: CGRect) {
        let gradientLayer = CAGradientLayer()

        gradientLayer.frame = layer.bounds
        gradientLayer.colors = [UIColor.red.cgColor, UIColor.green.cgColor, UIColor.yellow.cgColor]

        /**
         Defaults:
            start point x: 0.5, y: 0.0
            end point x: 0.5, y: 1.0
         Results in a vertical line segment, which the gradient always goes
         perpendicular to.

         Default gradient, therefore, goes from top to bottom.

         To achieve a left to right gradient, set the start and end points
         along a horizontal line, where the start point is to the left
         of the end point.
        */
        gradientLayer.startPoint = CGPoint(x: 0, y: 1)
        gradientLayer.endPoint = CGPoint(x: 1, y: 1)

        layer.addSublayer(gradientLayer)
    }
}

Replicator Layer

class MyView: UIView {
    override func draw(_ rect: CGRect) {
        let replicatorLayer = CAReplicatorLayer()
        replicatorLayer.frame = bounds
        replicatorLayer.instanceCount = 30

        // Delay in seconds
        replicatorLayer.instanceDelay = CFTimeInterval(1/Float(replicatorLayer.instanceCount))

        /**
         If false, the layer will flatten it's sublayers at Z = 0.

         If true, the layer will behave like a CATransformLayer,
         which is a true 3D layer heirarchy.

         Defaults to false.
        */
        replicatorLayer.preservesDepth = false

        /**
         Starts at white by default (1,1,1) and subtracts 1/30 from blue and green with each
         instance.

         Results in the instances transitioning from white to red.
        */
        replicatorLayer.instanceRedOffset = 0.0
        replicatorLayer.instanceBlueOffset =  Float(-1.0) / Float(replicatorLayer.instanceCount)
        replicatorLayer.instanceGreenOffset = replicatorLayer.instanceBlueOffset
        replicatorLayer.instanceAlphaOffset = 0.0

        let angleInRadians: CGFloat = CGFloat(2 * M_PI) / CGFloat(replicatorLayer.instanceCount)

        /**
         Rotates the instances by an angle in radians about the Z-axis, which
         comes directly out of the plane towards the viewer.

         Values for each axis range from -1 to 1.
        */
        replicatorLayer.instanceTransform = CATransform3DMakeRotation(angleInRadians, 0, 0, 1.0)

        let instanceLayer = CALayer()
        let instanceWidth: CGFloat = 5.0
        let centerX = (bounds.width / 2.0) - (instanceWidth / 2.0)

        /**
         Set the frame of the instance layer relative to the replication layer.
        */
        instanceLayer.frame = CGRect(x: centerX, y: 0, width: instanceWidth, height: instanceWidth * 4)
        instanceLayer.backgroundColor = UIColor.white.cgColor

        // Set initial opacity to 0 for fade animation.
        instanceLayer.opacity = 0.0

        /**
         Add a fade animation for each instance.
        */
        let fadeAnimation = CABasicAnimation(keyPath: "opacity")
        fadeAnimation.fromValue = 1.0
        fadeAnimation.toValue = 0.0
        fadeAnimation.duration = 1.0 // in seconds
        fadeAnimation.repeatCount = Float(Int.max)
        instanceLayer.add(fadeAnimation, forKey: nil)

        replicatorLayer.addSublayer(instanceLayer)
        layer.addSublayer(replicatorLayer)
    }
}

References

References