After wrapping up our overview of Animation, this article takes a look at Layer, another part of Core Animation. As one of the core contents of the framework, the CALayer and its subclasses serve as the cornerstone of the view interface, which is not only powerful in drawing but also functional. Of course, the Layer section is very complex, and it is neither practical nor efficient to cover each type. This article will choose a few layers that are closely related to animation as cutting points and leave the rest for you to explore (don’t stay in the imagination stage).

CAGradientLayer

CAGradientLayer is used to generate a smooth gradient of two or more colors. While the layers themselves are not animated, we can use gradient colors to create implicit animations, a typical example of which is the iPhone’s slide to unlock.

To achieve the gradient effect we need to set the following properties:

  • StartPoint: The starting point of the gradient. By default (0, 0) indicates the upper left corner.

  • EndPoint: indicates the endPoint of the gradient. By default, (1, 1) indicates the lower right corner.

  • Colors: An array of colors for the gradient.

  • Locations: An optional value. The default value is nil. When you set it manually, be careful that the number is consistent with colors.

Below directly on the code:

override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = UIColor.gray let gradientLayer = CAGradientLayer() gradientLayer.frame = CGRect.init(x: 50, y: 100, width: 200, height: 40) gradientLayer.colors = [ UIColor.black.cgColor, UIColor.white.cgColor, Uicolor.black.cgcolor] gradientlayer. startPoint = cgpoint.init (x: 0, y: 0.5) gradientlayer. endPoint = cgpoint.init (x: 0, y: 0.5) gradientlayer. endPoint = CGPoint. 1, y: 0.5) gradientLayer. Locations = [0.25,0.5,0.75]; view.layer.addSublayer(gradientLayer) let gradientAnimation = CABasicAnimation(keyPath: "Locations") gradientAnimation. FromValue = [0.0, 0.0, 0.25] gradientAnimation. ToValue = [0.75, 1.0, 1.0] gradientAnimation. Duration = 3.0 gradientAnimation. 100 unlock repeatCount = = UILabel. Init (frame: GradientLayer. Bounds) unlock?. Alpha = 0.5; unlock? .text = "Slide to unlock >>" unlock? .textAlignment = .center; gradientLayer.mask = unlock? .layer; gradientLayer.add(gradientAnimation, forKey: nil) }

In the above code, after creating a new layer, set the gradient color set, then set the startPoint, endPoint properties to specify the gradient path, and finally specify the gradient location of the color set. With the layer Settings done we added a simple shift animation to move the gradient band and added the text Label.

CAShapeLayer

CAShapeLayer is a layer subclass drawn using vector graphics instead of bitmaps. You specify attributes such as color and line width, use CGPath to define the shape you want to draw, and the CAShapeLayer automatically renders it. Of course, you can also use Core Graphics to draw a path directly into the content of the original CALyer. There are several advantages to using CAShapeLayer over straight down:

  • Render fast. CAShapeLayer uses hardware acceleration to draw the same Graphics much faster than Core Graphics.

  • Use memory efficiently. A CAShapeLayer does not need to create a host graph like a regular CALayer, so no matter how large it is, it does not take up too much memory.

  • Will not be clipped by layer boundaries. A CAShapeLayer can be drawn outside the boundaries.

CAShapeLayer is commonly used in pull-down refresh animations and various curve drawing animations. Common attributes are:

  • Path: The frame path of the layer.

  • FillColor: fillColor.

  • LineWidth: lineWidth.

  • LineCap: Edge style.

  • LineDashPattern: An optional type that sets the virtual and real height of the edges. For example, [2, 3] means that the boundary line is dotted with solid, the height of the solid line is 3, and the height of the dotted line is 2.

  • StrokeStart: The starting position of the edge. Valid values range from 0.0 to 1.0, but are sometimes set to negative for specific effects with strokeEnd.

  • StrokeEnd: indicates the end position of the edge. The value ranges from 0.0 to 1.0.

Let’s look at the CAShapeLayer implementation of the pull-down Refresh style animation:

override func viewDidLoad() { super.viewDidLoad() let ovalShapeLayer: CAShapeLayer = CAShapeLayer() ovalShapeLayer.path = UIBezierPath.init(ovalIn: CGRect.init(x: 100, y: 100, width: 80, height: 80)).cgPath ovalShapeLayer.fillColor = UIColor.clear.cgColor ovalShapeLayer.strokeColor = UIColor.blue.cgColor OvalShapeLayer. Our lineWidth = 4 ovalShapeLayer. LineDashPattern = [2, 3] the layer. The addSublayer ovalShapeLayer let airplaneLayer = CALayer() let airplaneImage = UIImage(named: "airplane.png")! Bounds = CGRect(x: 0.0, y: 0.0, width: 0) bounds = CGRect(x: 0.0, y: 0.0, width: 0) airplaneImage.size.width, height: airplaneImage.size.height) airplaneLayer.position = CGPoint(x: 180, y: 140) view.layer.addSublayer(airplaneLayer) let strokeStartAnimation = CABasicAnimation(keyPath: "StrokeStart") strokeStartAnimation. FromValue = 1.0 strokeStartAnimation. ToValue = 1.0 let strokeEndAnimation = CABasicAnimation(keyPath: "StrokeEnd") strokeEndAnimation. FromValue = 0.0 strokeEndAnimation. ToValue = 1.0 let strokeAnimationGroup = CAAnimationGroup () strokeAnimationGroup. Duration = 1.5 strokeAnimationGroup. RepeatDuration = 5.0 strokeAnimationGroup.animations = [strokeStartAnimation, strokeEndAnimation] ovalShapeLayer.add(strokeAnimationGroup, forKey: nil) let flightAnimation = CAKeyframeAnimation(keyPath: "position") flightAnimation.path = ovalShapeLayer.path flightAnimation.calculationMode = kCAAnimationPaced let airplaneOrientationAnimation = CABasicAnimation(keyPath: "transform.rotation") airplaneOrientationAnimation.fromValue = 0 airplaneOrientationAnimation.toValue = 2 * M_PI let FlightAnimationGroup = CAAnimationGroup () flightAnimationGroup. Duration = 1.5 flightAnimationGroup. RepeatDuration = 5.0 flightAnimationGroup.animations = [flightAnimation, airplaneOrientationAnimation] airplaneLayer.add(flightAnimationGroup, forKey: nil) view.backgroundColor = UIColor.gray }

In the above code, we first create two Layer objects and set the properties, host diagram, and starting position respectively. Then we add animation groups to each Layer. One important detail to note is that the start and end points in the ovalShapeLayer animation group are set differently, where strokeStart is from -1 to 1 and strokeEnd is from 0 to 1. After the start position of the strokeStart causes the movement speed to increase, thus creating the animation effect of the strokeStart chasing the strokeEnd in the timeline. For the airplaneLayer, we set its starting position on the right vertical tangent of the ovalShapeLayer to achieve the desired effect.

CAReplicatorLayer

CAReplicatorLayer is mainly designed to efficiently generate many similar layers. It can copy the layer of its own child layer, and the copied layer has the same properties, position, deformation and animation as the original child layer. A picture is worth a thousand words, let’s take a look at the effect first:

We copy the CALayer on the left through CAReplicatorLayer, and then delay the animation in turn.

override func viewDidLoad() { super.viewDidLoad() let replicatorLayer = CAReplicatorLayer() replicatorLayer.frame = CGRect.init(x: 100, y: 100, width: 90, height: 40) replicatorLayer.backgroundColor = UIColor.white.cgColor view.layer.addSublayer(replicatorLayer) let crcleBallLayer =  CALayer() crcleBallLayer.backgroundColor = UIColor.green.cgColor crcleBallLayer.frame = CGRect.init(x: 0, y: 10, width: 20, height: 20) crcleBallLayer.cornerRadius = 10 let basicAniamtion = CABasicAnimation.init(keyPath: "Transform.scale ") basicAniamtion.fromValue = 1.0 BasicAniamtion.toValue = 0.2 BasicAniamtion.duration = 0.5 basicAniamtion.autoreverses = true basicAniamtion.repeatCount = 100 crcleBallLayer.add(basicAniamtion, forKey: Nil) replicatorLayer. AddSublayer (crcleBallLayer) replicatorLayer. InstanceCount = 3 / / copy number replicatorLayer instanceDelay = 0.3 / / delay / / every CALayer and displacement in front of the poor 30 replicatorLayer. InstanceTransform = CATransform3DTranslate(CATransform3DIdentity, 30, 0, 0 ) }

conclusion

This article concludes the summary of this Core Animation section with a brief introduction to several layers and code examples. Of course, the depth of Core Animation is far more than a few simple articles can summarize, but I still hope that my learning summary can be helpful to readers. It’s the worst of times and the best of times, and it’s all up to us.