Swift动画 —— 登陆页面动画(一)

1,709 阅读2分钟
  • 小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。 下面是想要实现的动画效果:

在这里插入图片描述

这里拆分成三个部分来完成,这里先来完成LOGO动画。 先把LOGO图片添加到Assets里面,声明logoImageView属性以及之后所期望的logo大小让VC持有。

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

声明一个setupUI方法并在viewDidAppear里面调用,在setupUI里面设置好logoImageView的frame等属性,并让其变成可以互动,添加点击手势。

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

在点击手势的响应方法里面添加抖动特效,这里使用CABasicAnimation中的position,然后设置好抖动的返回,动画时间等属性就可以达到想要的抖动特效。

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

接下来要做的就是Logo上移的动画,这里只需要简单的使用UIView.animate就好了,这里方法传进来一个闭包并在completion里面对其进行调用,主要是因为后面两个动画都在这个logo动画执行之后执行,所以可以在调用方法的时候传进来。

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

下一步就是中间线的绘制动画以及中间button的浮现动画了,这一部需要用到UIBezierPath来画线。 目前的效果:

请添加图片描述

完整代码:

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