美文网首页iOS14开发
iOS14开发-动画

iOS14开发-动画

作者: YungFan | 来源:发表于2021-04-20 20:26 被阅读0次

    介绍

    动画往往能起到增强用户体验的作用,在 iOS 开发中,我们可以使用 UIKit 提供的动画来实现,简称 UIView 动画。UIView 动画实质上是对 Core Animation(核心动画)的封装,提供简洁的动画 API。

    普通动画

    • API
    // 最完整
    open class func animate(withDuration duration: TimeInterval, delay: TimeInterval, options: UIView.AnimationOptions = [], animations: @escaping () -> Void, completion: ((Bool) -> Void)? = nil)
    
    open class func animate(withDuration duration: TimeInterval, animations: @escaping () -> Void, completion: ((Bool) -> Void)? = nil)
    
    // 最简单
    open class func animate(withDuration duration: TimeInterval, animations: @escaping () -> Void)
    
    • 参数含义
      • duration:动画持续时间。
      • delay:动画延迟执行的时间。
      • UIView.AnimationOptions:动画的过渡效果,可以组合使用。
      • animations:执行的动画。
      • completion:动画执行完毕后的操作。

    案例

    // 两个参数
    // 将需要执行动画的语句放入闭包即可
    UIView.animate(withDuration: 0.5) {
        view.backgroundColor = UIColor.red
    }
    
    // 闭包中可以同时执行多个属性的动画
    UIView.animate(withDuration: 0.5) {
        view.backgroundColor = UIColor.red
        view.center.y += 100
        view.alpha = 0
    }
    
    // 三个参数
    UIView.animate(withDuration: 0.5) {
        view.backgroundColor = UIColor.red
    } completion: { _ in
        print("动画执行完毕")
    }
    
    // 五个参数
    UIView.animate(withDuration: 0.5, delay: 0.5, options: .curveLinear) {
        view.backgroundColor = UIColor.red
    } completion: { _ in
        print("动画执行完毕")
    }
    
    // 放在performWithoutAnimation闭包中就会不执行动画
    UIView.animate(withDuration: 0.5) {
        view.backgroundColor = UIColor.red
        
        UIView.performWithoutAnimation {
            view.alpha = 0.2
        }
    }
    

    UIView.AnimationOptions

    常见的AnimationOptions有:

    • curveEaseInOut:时间曲线,慢速开始,然后加速,最后减速(默认值)。
    • curveEaseIn:时间曲线,慢速开始,之后越来越快。
    • curveEaseOut:时间曲线,快速开始,之后越来越慢。
    • curveLinear:时间曲线,匀速。
    • repeat:指定这个选项后,动画会无限重复。
    • autoreverse:往返动画,从开始执行到结束后,又从结束返回开始。
    • preferredFramesPerSecond30:指定动画刷新频率为30fps。
    • preferredFramesPerSecond60:指定动画刷新频率为60fps。

    停止动画

    view.layer.removeAllAnimations()
    

    弹簧动画

    • 又称 Spring 动画。
    • API
    open class func animate(withDuration duration: TimeInterval, delay: TimeInterval, usingSpringWithDamping dampingRatio: CGFloat, initialSpringVelocity velocity: CGFloat, options: UIView.AnimationOptions = [], animations: @escaping () -> Void, completion: ((Bool) -> Void)? = nil)
    
    • 参数含义
      • duration:动画持续时间。
      • delay:动画延迟执行的时间。
      • dampingRatio:震动效果,范围 0~1,数值越小震动效果越明显。
      • velocity:初始速度,数值越大初始速度越快。
      • UIView.AnimationOptions:动画的过渡效果,可以组合使用。(与普通动画类似)。
      • animations:执行的动画。
      • completion:动画执行完毕后的操作。

    案例

    // 三个动画进行对比
    UIView.animate(withDuration: 3.0, delay: 0, usingSpringWithDamping: 0.1, initialSpringVelocity: 0, options: .curveEaseIn, animations: {
        blueView.center.y += 300
    }, completion: nil)
    
    UIView.animate(withDuration: 3.0, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 10, options: .curveEaseIn, animations: {
        greenView.center.y += 300
    }, completion: nil)
    
    UIView.animate(withDuration: 3.0, delay: 0, usingSpringWithDamping: 0.9, initialSpringVelocity: 20, options: .curveEaseIn, animations: {
        redView.center.y += 300
    }, completion: nil)
    

    转场动画

    • API
    // 单个视图的过渡效果
    open class func transition(with view: UIView, duration: TimeInterval, options: UIView.AnimationOptions = [], animations: (() -> Void)?, completion: ((Bool) -> Void)? = nil)
    
    // 从旧视图转到新视图的动画效果
    open class func transition(from fromView: UIView, to toView: UIView, duration: TimeInterval, options: UIView.AnimationOptions = [], completion: ((Bool) -> Void)? = nil)
    
    • 参数含义
      • view:产生动画的视图。
      • fromView:动画过程中,fromView 会从父视图中移除。
      • toView:fromView 消失以后, toView 添加到父视图中。
      • duration:动画持续时间。
      • UIView.AnimationOptions:动画的过渡效果,可以组合使用。(以 transition 开头的才有过渡效果)。
      • animations:执行的动画。
      • completion:动画执行完毕后的操作。

    案例

    • 方式一
    UIView.transition(with: self.redView, duration: 2.0, options: .transitionCurlUp, animations: { 
        let orangeView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))    
        orangeView.center = self.redView.center
        orangeView.backgroundColor = UIColor.orange  
        self.redView.addSubview(orangeView)    
    }, completion: nil)
    
    • 方式二
    let orangeView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
    orangeView.backgroundColor = UIColor.orange
    UIView.transition(from: self.redView, to: orangeView, duration: 2.0, options: .transitionFlipFromRight, completion: nil)
    

    坐标转换

    思考:在方式一中设置的orangeView.center = self.redView.center并没有实现预期的效果,为什么?

    因为redVieworangeView参考的不是同一个坐标系,需要进行坐标转换

    坐标转换分为两种,一种是 CGPoint 转换,一种是 CGRect 转换。

    CGPoint转换
    // self.view(from参数)的self.redView.center(point参数)转换到self.redView(调用者)中
    orangeView.center = self.redView.convert(self.redView.center, from: self.view)
    // self.view(调用者)将self.redView.center(point参数)转换到self.redView(to参数)中
    orangeView.center = self.view.convert(self.redView.center, to: self.redView)
    
    CGRect转换
    // self.redView(from参数)的orangeView.frame(rect参数)转换到self.view(调用者)中
    orangeView.frame = self.view.convert(orangeView.frame, from: self.redView)
    // self.view(调用者)将self.redView.frame(rect参数)转换到self.redView(to参数)中
    self.redView.frame = self.view.convert(self.redView.frame, to: self.redView)
    

    关键帧动画

    • API
    open class func animateKeyframes(withDuration duration: TimeInterval, delay: TimeInterval, options: UIView.KeyframeAnimationOptions = [], animations: @escaping () -> Void, completion: ((Bool) -> Void)? = nil)
    
    open class func addKeyframe(withRelativeStartTime frameStartTime: Double, relativeDuration frameDuration: Double, animations: @escaping () -> Void)
    
    • 参数含义
      • duration:动画持续的总时间。
      • delay:动画延迟执行的时间。
      • UIView.KeyframeAnimationOptions:动画的过渡效果,可以组合使用。
      • animations:执行的关键帧动画。
      • completion:动画执行完毕后的操作。
      • frameStartTime:动画开始的时间(占总时间的比例)。
      • relativeDuration:动画持续时间(占总时间的比例)。
      • animations:执行的帧动画。

    案例

    class ViewController: UIViewController {
        @IBOutlet var leaf: UIImageView!
    
        override func viewDidLoad() {
            super.viewDidLoad()
        }
    
        override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
            UIView.animateKeyframes(withDuration: 6.0, delay: 0, options: .calculationModeCubic, animations: {
                UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.1, animations: {
                    self.leaf.center = CGPoint(x: 108, y: 260)
                })
    
                UIView.addKeyframe(withRelativeStartTime: 0.1, relativeDuration: 0.1, animations: {
                    self.leaf.center = CGPoint(x: 138, y: 340)
                })
    
                UIView.addKeyframe(withRelativeStartTime: 0.2, relativeDuration: 0.1, animations: {
                    self.leaf.center = CGPoint(x: 168, y: 420)
                })
    
                UIView.addKeyframe(withRelativeStartTime: 0.3, relativeDuration: 0.1, animations: {
                    self.leaf.center = CGPoint(x: 200, y: 490)
                })
    
                UIView.addKeyframe(withRelativeStartTime: 0.4, relativeDuration: 0.1, animations: {
                    self.leaf.center = CGPoint(x: 248, y: 570)
                })
    
                UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.1, animations: {
                    self.leaf.center = CGPoint(x: 278, y: 630)
                })
    
                UIView.addKeyframe(withRelativeStartTime: 0.6, relativeDuration: 0.1, animations: {
                    self.leaf.center = CGPoint(x: 308, y: 690)
                })
    
                UIView.addKeyframe(withRelativeStartTime: 0.7, relativeDuration: 0.1, animations: {
                    self.leaf.center = CGPoint(x: 318, y: 770)
                })
    
                UIView.addKeyframe(withRelativeStartTime: 0.8, relativeDuration: 0.1, animations: {
                    self.leaf.center = CGPoint(x: 328, y: 860)
                })
    
                UIView.addKeyframe(withRelativeStartTime: 0.9, relativeDuration: 0.1, animations: {
                    self.leaf.transform = CGAffineTransform(rotationAngle: CGFloat(Float.pi * 0.25))
                })
            }, completion: nil)
        }
    }
    

    UIView.KeyframeAnimationOptions

    常见的KeyframeAnimationOptions有:

    • calculationModeLinear:运算模式,连续。
    • calculationModeDiscrete:运算模式,离散。
    • calculationModePaced:运算模式,均匀执行。
    • calculationModeCubic:运算模式,平滑。
    • calculationModeCubicPaced:运算模式,平滑均匀。
    • repeat:指定这个选项后,动画会无限重复。
    • autoreverse:往返动画,从开始执行到结束后,又从结束返回开始。

    相关文章

      网友评论

        本文标题:iOS14开发-动画

        本文链接:https://www.haomeiwen.com/subject/orqolltx.html