• Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

Here are the animations you want to achieve:

Here is divided into three parts to complete, here first to complete the LOGO animation. First add the LOGO image to Assets, declare the logoImageView property and then the desired size of the LOGO for the VC to hold.

private let logoSize = CGSize(width: 250, height: 40)
private var logoImageView: UIImageView!
Copy the code

Declare a setupUI method and call it in viewDidAppear, and in setupUI set the frame properties of logoImageView and make it interactive, add click gestures.

   private func setupUI() {

        // Initialize the logo at the center of screen
        logoImageView = UIImageView(frame: CGRect(x: view.frame.width/2 - logoSize.width/2,
                                                  y: view.frame.height/2 - logoSize.height/2,
                                                  width: logoSize.width,
                                                  height: logoSize.height))
        logoImageView.contentMode = .scaleToFill
        logoImageView.image = UIImage(named: "logo_icon")
        logoImageView.isUserInteractionEnabled = true
        logoImageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(shakeLogo)))
        view.addSubview(logoImageView)
        }
Copy the code

Add the jitter effect in the response method of click gesture. Here, use position in CABasicAnimation, and then set the return of jitter, animation time and other properties to achieve the desired jitter effect.

let animation = CABasicAnimation(keyPath: "Position ") animation.duration = 0.07 animation.repeatCount = 4 animation.autoreverses = true animation.fromValue = NSValue(cgPoint: CGPoint(x: logoImageView.center.x - 10, y: logoImageView.center.y)) animation.toValue = NSValue(cgPoint: CGPoint(x: logoImageView.center.x + 10, y: logoImageView.center.y)) logoImageView.layer.add(animation, forKey: "position")Copy the code

The next step is to animate the Logo up, which simply uses UIView.animate. The method here passes in a closure and calls it in Completion, mainly because the next two animations are executed after the Logo animation. So you can pass it in when you call the method.

Private func animateLogo(completion: @escaping ()->()) {uiviet.animate (withDuration: 1.0, animations: { self.logoImageView.frame = self.logoImageView.frame.offsetBy(dx: 0, dy: -250) }, completion: { _ in completion() }) }Copy the code

The next step is to animate the middle line and the emergence of the middle button, this one using UIBezierPath to draw the line. Current results:

Complete code:

import UIKit class ViewController: UIViewController { private let logoSize = CGSize(width: 250, height: 40) private var logoImageView: UIImageView! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. setupUI() animateLogo { } } private func setupUI() { // Initialize the logo at the center of screen logoImageView = UIImageView(frame: CGRect(x: view.frame.width/2 - logoSize.width/2, y: view.frame.height/2 - logoSize.height/2, width: logoSize.width, height: logoSize.height)) logoImageView.contentMode = .scaleToFill logoImageView.image = UIImage(named: "logo_icon") logoImageView.isUserInteractionEnabled = true logoImageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(shakeLogo))) view.addSubview(logoImageView) } @objc private func shakeLogo() { let animation = CABasicAnimation(keyPath: "Position ") animation.duration = 0.07 animation.repeatCount = 4 animation.autoreverses = true animation.fromValue = NSValue(cgPoint: CGPoint(x: logoImageView.center.x - 10, y: logoImageView.center.y)) animation.toValue = NSValue(cgPoint: CGPoint(x: logoImageView.center.x + 10, y: logoImageView.center.y)) logoImageView.layer.add(animation, forKey: "position") } private func animateLogo(completion: @escaping ()->()) {uiview.animate (withDuration: 1.0, animations: { self.logoImageView.frame = self.logoImageView.frame.offsetBy(dx: 0, dy: -250) }, completion: { _ in completion() }) } }Copy the code