本文共 7560 字,大约阅读时间需要 25 分钟。
简单的平移、缩放和旋转以及渐隐渐显,都可以使用
UIView.animate(withDuration: 0.25, animations: { // 最终的结果显示 }) { (_) in // 动画完成之后要进行的操作 }
如果是稍微复杂的动画,比如沿着曲线运动,就可以考虑使用关键帧动画CAKeyframeAnimation实现。
效果图1:
效果图2:
效果1代码:
//// ViewController.swift// 关键帧动画CAKeyframeAnimation//// Created by iOS on 2018/5/22.// Copyright © 2018年 weiman. All rights reserved.//import UIKitclass ViewController: UIViewController { @IBOutlet weak var redView: UIView! @IBOutlet weak var purpleView: UIView! override func viewDidLoad() { super.viewDidLoad() redView.layer.cornerRadius = redView.frame.size.width/2.0 redView.layer.masksToBounds = true purpleView.layer.cornerRadius = purpleView.frame.size.width/2.0 purpleView.layer.masksToBounds = true animationOne() animationTwo() } //一个数组,提供了一组关键帧的值, 当使用path的 时候 values的值自动被忽略。 func animationOne() { /* 提供一组关键帧位置,使得动画view的中心依次落在这些关键点上,形成动画 */ let animation = CAKeyframeAnimation(keyPath: "position") let value1: NSValue = NSValue(cgPoint: CGPoint(x: 100, y: 100)) let value2: NSValue = NSValue(cgPoint: CGPoint(x: 200, y: 100)) let value3: NSValue = NSValue(cgPoint: CGPoint(x: 200, y: 200)) let value4: NSValue = NSValue(cgPoint: CGPoint(x: 100, y: 200)) let value5: NSValue = NSValue(cgPoint: CGPoint(x: 100, y: 300)) let value6: NSValue = NSValue(cgPoint: CGPoint(x: 200, y: 400)) animation.values = [value1, value2, value3, value4, value5, value6] animation.repeatCount = MAXFLOAT animation.autoreverses = true animation.duration = 4.0 animation.isRemovedOnCompletion = false animation.fillMode = kCAFillModeForwards animation.timingFunctions = [CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)] animation.delegate = self redView.layer.add(animation, forKey: nil) } func animationTwo() { let screenWidth = UIScreen.main.bounds.size.width let screenHeight = UIScreen.main.bounds.size.height let animation = CAKeyframeAnimation(keyPath: "position") let value1 = NSValue(cgPoint: CGPoint(x: screenWidth/2.0, y: 0)) let value2 = NSValue(cgPoint: CGPoint(x: screenWidth, y: 100)) let value3 = NSValue(cgPoint: CGPoint(x: 0, y: screenHeight/2.0)) let value4 = NSValue(cgPoint: CGPoint(x: screenWidth/2.0, y: screenHeight)) animation.values = [value1,value2,value3,value4,value1] animation.repeatCount = MAXFLOAT animation.autoreverses = true animation.duration = 6.0 animation.isRemovedOnCompletion = false animation.fillMode = kCAFillModeForwards animation.timingFunctions = [CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)] animation.delegate = self purpleView.layer.add(animation, forKey: nil) }}extension ViewController: CAAnimationDelegate { }
效果2代码:
//// SecondViewController.swift// 关键帧动画CAKeyframeAnimation//// Created by iOS on 2018/5/22.// Copyright © 2018年 weiman. All rights reserved.//import UIKitclass SecondViewController: UIViewController { @IBOutlet weak var blueView: UIView! @IBOutlet weak var greenView: UIView! @IBOutlet weak var yellowView: UIView! let screenWidth = UIScreen.main.bounds.size.width let screenHeight = UIScreen.main.bounds.size.height override func viewDidLoad() { super.viewDidLoad() blueView.layer.cornerRadius = blueView.frame.size.width/2.0 blueView.layer.masksToBounds = true greenView.layer.cornerRadius = greenView.frame.size.width/2.0 greenView.layer.masksToBounds = true yellowView.layer.cornerRadius = yellowView.frame.size.width/2.0 yellowView.layer.masksToBounds = true animationPathBlue() animationGreen() animationYellow() } @IBAction func back(_ sender: UIButton) { dismiss(animated: true, completion: nil) } /// 使用path的方式实现动画 /* 这是一个 CGPathRef 对象,默认是空的,当我们创建好CAKeyframeAnimation的实例的时候,可以通过制定一个自己定义的path来让 某一个物体按照这个路径进行动画。这个值默认是nil 当其被设定的时候 values 这个属性就被覆盖 */ /// 沿着圆周运动 func animationPathBlue() { // 创建动画对象 let animation = CAKeyframeAnimation(keyPath: "position") // 创建一个CGPathRef对象,就是动画的路线 let path = CGMutablePath() // 自动沿着弧度移动 path.addEllipse(in: CGRect(x: 0, y: 50, width: screenWidth, height: 100)) animation.path = path animation.autoreverses = true animation.repeatCount = MAXFLOAT animation.isRemovedOnCompletion = false animation.fillMode = kCAFillModeForwards animation.duration = 3.0 animation.timingFunctions = [CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)] animation.delegate = self blueView.layer.add(animation, forKey: nil) } /// 沿着直线运动 func animationGreen() { // 创建动画对象 let animation = CAKeyframeAnimation(keyPath: "position") // 创建一个CGPathRef对象,就是动画的路线 let path = CGMutablePath() // 设置开始位置 path.move(to: CGPoint(x: 0, y: 150)) // 沿着直线移动 /* Z字轨迹 */ path.addLine(to: CGPoint(x: screenWidth, y: 150)) path.addLine(to: CGPoint(x: 0, y: 200)) path.addLine(to: CGPoint(x: screenWidth, y: 200)) path.addLine(to: CGPoint(x: 0, y: 200)) path.addLine(to: CGPoint(x: screenWidth, y: 150)) animation.path = path animation.autoreverses = true animation.repeatCount = MAXFLOAT animation.isRemovedOnCompletion = false animation.fillMode = kCAFillModeForwards animation.duration = 6.0 animation.timingFunctions = [CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)] animation.delegate = self greenView.layer.add(animation, forKey: nil) } /// 曲线运动 func animationYellow() { // 创建动画对象 let animation = CAKeyframeAnimation(keyPath: "position") // 创建一个CGPathRef对象,就是动画的路线 let path = CGMutablePath() // 设置开始位置 path.move(to: CGPoint(x: 0, y: screenHeight)) // 沿着曲线移动 path.addCurve(to: CGPoint(x: screenWidth, y: screenHeight/2.0), control1: CGPoint(x: screenWidth/4.0, y: screenHeight/4.0), control2: CGPoint(x: screenWidth/2.0, y: screenHeight/2.0)) // path.addCurve(to: CGPoint(x: 150.0, y: 275.0),// control1: CGPoint(x: 250.0, y: 275.0),// control2: CGPoint(x: 90.0, y: 120.0))//// path.addCurve(to: CGPoint(x: 250.0, y: 275.0),// control1: CGPoint(x: 350.0, y: 275.0),// control2: CGPoint(x: 110.0, y: 120.0))//// path.addCurve(to: CGPoint(x: 350.0, y: 275.0),// control1: CGPoint(x: 450.0, y: 275.0),// control2: CGPoint(x: 130.0, y: 120.0)) animation.path = path animation.autoreverses = true animation.repeatCount = MAXFLOAT animation.isRemovedOnCompletion = false animation.fillMode = kCAFillModeForwards animation.duration = 3.0 animation.timingFunctions = [CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)] animation.delegate = self yellowView.layer.add(animation, forKey: nil) }}extension SecondViewController: CAAnimationDelegate { }
demo地址:
转载地址:http://uiujl.baihongyu.com/