iOS14开发

iOS14开发-动画

2021-04-20  本文已影响0人  YungFan

介绍

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

案例

// 两个参数
// 将需要执行动画的语句放入闭包即可
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有:

停止动画

view.layer.removeAllAnimations()

弹簧动画

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)

案例

// 三个动画进行对比
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)

转场动画

// 单个视图的过渡效果
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)

案例

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)

关键帧动画

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)

案例

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有:

上一篇 下一篇

猜你喜欢

热点阅读