UIswift

iOS核心动画小结(swift)

2018-05-29  本文已影响163人  Andy_Ron

本文所有示例代码都是Swift4,参看文末链接

Core Animation是IOS和OS X平台上负责图形渲染与动画的基础框架。Core Animation可以作用与动画视图或者其他可视元素,为你完成了动画所需的大部分绘画工作。你只需要配置少量的动画参数(如开始点的位置和结束点的位置)即可使用Core Animation的动画效果。Core Animation将大部分实际的绘图任务交给了图形硬件来处理,图形硬件会加速图形渲染的速度。这种自动化的图形加速技术让动画拥有更高的帧率并且显示效果更加平滑,不会加重CPU的负担而影响程序的运行速度。

Core Animation常用类继承关系

上图少了iOS9才引入的CASpringAnimation, 它继承至CABasicAnimation

一、常用属性

这些属性一般是在基类CAAnimation和协议CAMediaTiming中,是几种动画类共用的属性。

public protocol CAAnimationDelegate : NSObjectProtocol {    
    @available(iOS 2.0, *)
    optional public func animationDidStart(_ anim: CAAnimation)

    @available(iOS 2.0, *)
    optional public func animationDidStop(_ anim: CAAnimation, finished flag: Bool)
}

二、基础动画(CABasicAnimation)

基础动画就是从一个状态值(fromValue)变换成另一个状态值(toValue),特有的属性:

        let moveView = UIView(frame:  CGRect(x: 20, y: 240, width: 70, height: 70))
        moveView.center = CGPoint(x: 40, y: 200)
        moveView.backgroundColor = UIColor.red
        view.addSubview(moveView)
        
        let moveAnim = CABasicAnimation(keyPath: "position")
        moveAnim.fromValue = NSValue(cgPoint: CGPoint(x: 40, y: 240))
        moveAnim.toValue = NSValue(cgPoint: CGPoint(x: 300, y: 240))
        moveAnim.duration = 2
        moveAnim.repeatCount = Float.infinity
        moveAnim.autoreverses = true

        moveView.layer.add(moveAnim, forKey: "moveAnim")
位移动画
另外CABasicAnimation还可以做旋转、比例缩放、背景颜色变化、内容(图片)变化、透明度变化、圆角变化、指定大小变化等动画。(这些我都写了一些示例代码,链接在文末)
这些动画的代码形式基本都差不多,先建立视图,然后创建CABasicAnimation类型动画对象,并指定不同的fromValuetoValue等属性,最后把动画对象加入到视图的CALayer层。 基础动画

三、关键帧动画(CAKeyframeAnimation)

按照指定的一串值进行动画,好像拍电影一样的一帧一帧的效果。

CABasicAnimation可看做是最多只有2个关键帧(开始和结束)的CAKeyframeAnimation

下面的代码通过values做成抖动的动画:

        let anima = CAKeyframeAnimation(keyPath: "transform.rotation")
        anima.values = [-Double.pi/180*4,Double.pi/180*4, -Double.pi/180*4]
        anima.repeatCount = Float.infinity
        animView.layer.add(anima, forKey: "shake")

使用path配合贝塞尔曲线就可以做成如下效果:

代码

        let tempView = UIView(frame: CGRect(x: 50, y: 100, width: 250, height: 500))
        let bezierPath = UIBezierPath(ovalIn: tempView.frame)
        let orbitAnim = CAKeyframeAnimation(keyPath: "position")
        orbitAnim.duration = 5
        orbitAnim.path = bezierPath.cgPath
        orbitAnim.calculationMode = kCAAnimationPaced
        orbitAnim.fillMode = kCAFillModeForwards
        orbitAnim.repeatCount = Float.infinity
        orbitAnim.rotationMode = kCAAnimationRotateAutoReverse
        animView.layer.add(orbitAnim, forKey: "orbitAnim")
        
        let shapeLayer = CAShapeLayer()
        shapeLayer.strokeColor = UIColor.purple.cgColor
        shapeLayer.fillColor = UIColor.clear.cgColor
        shapeLayer.lineWidth = 0.5
        shapeLayer.lineJoin = kCALineJoinRound
        shapeLayer.lineCap = kCALineCapRound
        shapeLayer.path = bezierPath.cgPath
        view.layer.addSublayer(shapeLayer)

四、组动画(CAAnimationGroup)

组动画顾名思义就是把不同的动画组合起来,比如下面的代码:

        // 位移
        let anima1 = CABasicAnimation(keyPath: "position")
        anima1.fromValue = NSValue(cgPoint: CGPoint(x: 40, y: 240))
        anima1.toValue = NSValue(cgPoint: CGPoint(x: 300, y: 240))
        // 缩放
        let anima2 = CABasicAnimation(keyPath: "transform.scale")
        anima2.fromValue = NSNumber.init(value: 0.8)
        anima2.toValue = NSNumber.init(value: 2.0)
        // 旋转
        let anima3 = CABasicAnimation(keyPath: "transform.rotation")
        anima3.toValue = Double.pi*4
        // 组合
        let groupAnimation = CAAnimationGroup()
        groupAnimation.animations = [anima1, anima2, anima3]
        groupAnimation.duration = 3.0
        
        animView.layer.add(groupAnimation, forKey: nil)

组合后的动画效果就是在移动的同时,也在缩放和旋转。

组合动画

五、过渡动画(CATransition)

CATransition用于做过渡动画或者转场动画,能够为层提供移出屏幕和移入屏幕的动画效果。

系统公开API 效果说明 是否支持方向
kCATransitionFade 淡出效果
kCATransitionMoveIn 新视图移动到旧视图上
kCATransitionPush 新视图推出旧视图
kCATransitionReveal 移开旧视图显示新视图

其他还有一些非系统公开的过渡类型:

["cube", "suckEffect", "rippleEffect", "pageCurl", "pageUnCurl", "oglFlip"]

kCATransitionFromRight 从右侧进入
kCATransitionFromLeft 从左侧进入
kCATransitionFromTop 从顶部进入
kCATransitionFromBottom 从底部进入
过渡动画

六、弹簧动画 CASpringAnimation

常用属性

        // 不同的keypath,不同的效果
        let springAnimation = CASpringAnimation(keyPath: "position.y")
        
        if springAnimation.keyPath == "position" {
            springAnimation.fromValue = NSValue.init(cgPoint: self.jellyView.layer.position)
            springAnimation.toValue = NSValue.init(cgPoint: point)
        } else if springAnimation.keyPath == "position.x" {
            springAnimation.fromValue = self.jellyView.layer.position.x
            springAnimation.toValue = point.x
        } else if springAnimation.keyPath == "position.y" {
            springAnimation.fromValue = self.jellyView.layer.position.y
            springAnimation.toValue = point.y
        } else if springAnimation.keyPath == "bounds" {
            springAnimation.fromValue = NSValue.init(cgRect: CGRect(x: point.x, y: point.y, width: 60, height: 60))
            springAnimation.toValue = NSValue.init(cgRect: self.jellyView.frame)
        }
        
        springAnimation.mass = 5
        
        springAnimation.stiffness = 100
        
        springAnimation.damping = 10
        
        springAnimation.initialVelocity = 10
        springAnimation.duration = springAnimation.settlingDuration
        
        springAnimation.isRemovedOnCompletion = false
        
        self.jellyView.layer.add(springAnimation, forKey: "springAnimation")

keyPath不同时效果不同:


keyPath为bounds
keyPath为position
keyPath为position.y

代码:本文所有的示例代码都在https://github.com/andyRon/iOS-Animation

参考:
IOSAnimationDemo
iOS动画详解(学习动画看这一篇就够了)
一篇文章搞定 CASpringAnimation 弹簧动画
Core Animation 官方手册

上一篇下一篇

猜你喜欢

热点阅读