动画在软件开发中用的非常频繁,没有动画的软件,就类似于僵尸;所以对 iOS 常用的动画进行归纳总结,参考官方文档以及 UIView 和 QuartzCore 文档,受益颇多
iOS 常用动画分类
- UIViewAnimation
- Core Animation
- 第三方动画
iOS 常用动画思维导图
动画的基本属性
- Position 位置
- Opacity 透明度
- Scale 比例/大小
- Color 颜色
- Rotate 旋转
- Repeat 重复
- Spring 弹簧
- Status 显示和隐藏状态
- …
UIViewAnimation
UIView 一般形式动画
- beginAnimations:context: 标志动画代码开始
- commitAnimations: 标志动画代码结束,程序会创建新的线程,并准备运行动画
- setAnimationStartDate: 设置动画开始时间
- setAnimationsEnabled: 可以用来开启或禁止动画显示
- setAnimationDelegate: 设置代理,可以接收到UIView的代理方法
- setAnimationWillStartSelector: 设置动画开始前将发送给代理的方法
- setAnimationDidStopSelector: 设置动画停止后将发送给代理的方法
- setAnimationDuration: 设置动画持续时间
- setAnimationDelay: 设置一段时间,动画将在这段时间后开始执行
- setAnimationCurve: 设置动画曲线,如开始慢,后面快
- easeInOut 开始结束慢,中间快
- easeIn 开始慢, 加速运动
- easeOut 结束慢,减速运动
- linear 匀速运动
- setAnimationRepeatCount: 设置动画重复次数
- areAnimationEnabled: 检查是否已经启动动画
- setAnimationTransition: 设置动画的过渡效果
- none 无过渡效果
- flipFromLeft 从左边开始翻转
- flipFromRight 从左边开始翻转
- curlUp 向上翻页
- curlDown 向下翻页
代码示例
// 开始动画
UIView.beginAnimations("Identifier", context: nil)
// 设置动画代理
UIView.setAnimationDelegate(self)
// 通过 #selector 选择器 添加开始动画方法
UIView.setAnimationWillStart(#selector(animationAction))
// 通过 #selector 选择器 添加结束动画方法
UIView.setAnimationDidStop(#selector(animationAction))
// 设置动画时间间隔
UIView.setAnimationDuration(1.0)
// 设置动画延迟
UIView.setAnimationDelay(0)
// 设置动画开始的时间,默认是现在开始
UIView.setAnimationStart(Date())
// 设置动画曲线
UIView.setAnimationCurve(.easeInOut)
// 设置动画重复次数,默认是 0
UIView.setAnimationRepeatCount(0) // 0 无线循环
// 自动返回原始状态
UIView.setAnimationRepeatAutoreverses(false) // default = NO. used if repeat count is non-zero
// 设置动画的开始是从现在的状态开始, 默认是 false
UIView.setAnimationBeginsFromCurrentState(false)
// 用来开启或禁止动画显示
UIView.setAnimationsEnabled(true)
// 设置动画的过渡效果
UIView.setAnimationTransition(.curlUp, for: redView, cache: false)
// 设置 UIView 的动画属性
redView.transform = CGAffineTransform(rotationAngle: 90)
redView.transform = CGAffineTransform(scaleX: 0.3, y: 0.3)
redView.transform = CGAffineTransform(translationX: 0, y: 200)
// 动画的状态
print(UIView.areAnimationsEnabled)
// 标志动画代码结束,程序会创建新的线程,并准备运行动画
UIView.commitAnimations()
UIView 闭包式动画
基础动画
UIView.animate(withDuration: TimeInterval,
animations: ()->Void)
UIView.animate(withDuration: TimeInterval,
animations: ()->Void,
completion: ()->Void)
// 带动画曲线动画
UIView.animate(withDuration: TimeInterval,
delay: TimeInterval,
options: UIViewAnimationOptions,
animations: ()->Void,
completion: (()->Void)?)
// 带弹性动画
UIView.animate(withDuration: TimeInterval,
delay: TimeInterval,
usingSpringWithDamping: 0,
initialSpringVelocity: 0,
options: UIViewAnimationOptions,
animations: ()->Void,
completion: (()->Void)?)
关键帧动画
UIView.animateKeyframes(withDuration: TimeInterval,
delay: TimeInterval,
options: UIViewKeyframeAnimationOptions,
animations: ()->Void,
completion: (()->Void)?)
// 添加帧
UIView.addKeyframe(withRelativeStartTime: Double,
relativeDuration: Double,
animations: ()->Void)
转场动画
UIView.transition(with: UIView,
duration: TimeInterval,
options: UIViewAnimationOptions,
animations: ()->Void,
completion: (()->Void)?)
// toView added to fromView.superview, fromView removed from its superview
// 视图的添加和移除动画
UIView.transition(from: UIView,
to: UIView,
duration: TimeInterval,
options: UIViewAnimationOptions,
completion: (()->Void)?)
Core Animation 核心动画 (基于 CALayer
层级的动画)
参考资料:
Core Animation Programming Guide
实现步骤:
- (1) 建立
CAAnimation
子类对象 - (2) 设置它的参数 (代理、间隔、过渡效果、路径、)
- (3) 把这个带着参数的过渡添加到图层
CAAnimation
核心动画基础类,所有的动画类基于此类
核心属性:
- timingFunction - 一种可选的定时功能,用于定义动画的节奏
- UIViewAnimationCurveEaseInOut — 慢慢的开始,快速的过程,慢慢的结束
- UIViewAnimationCurveEaseIn — 慢慢的开始,直接加速到结束
- UIViewAnimationCurveEaseOut — 快速的开始,然后慢慢的结束
- UIViewAnimationCurveLinear — 匀速变化
- delegate CAAnimationDelegate 代理,处理动画过程
- isRemovedOnCompletion 默认为 true, 动画完成,自动从渲染树中移除掉
CAPropertyAnimation
抽象类,基于
CAAnimation
,专门用来设置 layer 属性的动画类
核心属性:
keyPath
用于描述动画属性的关键路径值
CAPropertyAnimation
的 keyPath
动画属性总结
属性 | 介绍 |
---|---|
anchorPoint | 锚点 |
backgroundColor | 背景色 |
borderColor | 边框颜色 |
borderWidth | 边框宽度 |
bounds | 大小 |
contents | 内容,可以放其他视图,包括图片 |
contentsRect | 内容大小 |
cornerRadius | 圆角 |
filters | 滤镜,模糊 |
hidden | 隐藏 |
mask | 遮挡, 控制内容视图展示大小 |
masksToBounds | 是否截切掉超过子视图的部分 |
opacity | 透明度 |
position | 位置 |
shadowColor | 阴影颜色 |
shadowOffset | 阴影偏移 |
shadowOpacity | 阴影的透明度 |
shadowPath | 阴影的路径 |
shadowRadius | 阴影的圆角 |
sublayers | 子图层 |
sublayerTransform | 子图层的变形 |
transform | 变形 |
zPosition | Z轴方向的位置 |
CABasicAnimation
基于 CAPropertyAnimation,动画的基础类
新增的的属性
- fromValue 定义了动画开始时的属性值
- toValue 定义了动画结束时的属性值
代码示例
let animation = CABasicAnimation(keyPath: "backgroundColor")
animation.fromValue = UIColor.green.cgColor
animation.toValue = UIColor.blue.cgColor
animation.duration = 1.0
animation.isRemovedOnCompletion = true
redView.layer.add(animation, forKey: nil)
CASpringAnimation
基于
CABasicAnimation
属性动画的弹性动画
新增的的属性
- damping 阻尼弹簧运动的摩擦力, 0.0 ~ 1.0
- initialVelocity 物体的初始速度
- mass 模拟物体的重量, > 0, default = 1
- settlingDuration 沉降时间
- stiffness 弹簧刚度系数, 0 ~ 100
代码示例
let springAnimation = CASpringAnimation(keyPath: "bounds.size")
springAnimation.toValue = NSValue(cgSize: CGSize(width: 250, height: 250))
springAnimation.duration = 1.0
springAnimation.damping = 0.5 // 0.0 to 1.0
springAnimation.initialVelocity = 10
springAnimation.mass = 5
springAnimation.stiffness = 50
redView.layer.add(springAnimation, forKey: nil)
CAKeyframeAnimation
基于属性动画,添加关键帧动画功能
添加的属性
- valuse 一个对象数组,指定关键帧动画值来使用
- path 点属性依据的路径
- keyTimes 一个可选的 NSNumber 对象数组, 给每个关键帧定义时间
- timingFunctions 一个可选的 CAMediaTimingFunction 对象数组定义为每个关键帧段过渡
- calculationMode 动画运行的模式
- kCAAnimationLinear
- kCAAnimationDiscrete
- kCAAnimationPaced
- kCAAnimationCubic
- kCAAnimationCubicPaced
- rotationMode 决定物体沿路径动画路径上如何旋转
- kCAAnimationRotateAuto
- kCAAnimationRotateAutoReverse
代码示例
let colorKeyframeAnimation = CAKeyframeAnimation(keyPath: "backgroundColor")
colorKeyframeAnimation.values = [UIColor.red.cgColor,
UIColor.green.cgColor,
UIColor.blue.cgColor]
colorKeyframeAnimation.keyTimes = [0, 0.5, 1]
colorKeyframeAnimation.duration = 2
colorKeyframeAnimation.calculationMode = kCAAnimationLinear
redView.layer.add(colorKeyframeAnimation, forKey: nil)
CAAnimationGroup
将多个动画组合和并发运行
delegate 和 isRemovedOnCompletion 在动画的属性数组中目前被忽略。
CAAnimationGroup 的 delegate 接收这些消息
新增加的属性
- animations
CAAnimation
数组,用于添加多个CAAnimation
动画
代码示例
let fadeOut = CABasicAnimation(keyPath: "opacity")
fadeOut.fromValue = 1
fadeOut.toValue = 0
fadeOut.duration = 1
let expandScale = CABasicAnimation()
expandScale.keyPath = "transform"
expandScale.valueFunction = CAValueFunction(name: kCAValueFunctionScale)
expandScale.fromValue = [1, 1, 1]
expandScale.toValue = [3, 3, 3]
let fadeAndScale = CAAnimationGroup()
fadeAndScale.animations = [fadeOut, expandScale]
fadeAndScale.duration = 1
redView.layer.add(fadeAndScale, forKey: nil)
CATransition
CAAnimation的子类
在图层状态之间提供动画转换的对象
提供了一个图层之间的过渡的动画
CATransition 有一个 type
和 subtype
来标识变换效果
新增加的属性
- startProgress 开始的进度 0~1
- endProgress 结束时的进度 0~1
- type 转换类型
- kCATransitionFade (default)
- kCATransitionMoveIn
- kCATransitionPush
- kCATransitionReveal
- subtype 基于运动方向预定义的转换
- kCATransitionFromLeft
- kCATransitionFromRight
- kCATransitionFromTop
- kCATransitionFromBottom
- filter 滤镜
代码示例
let animation = CATransition()
animation.duration = 1.0
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
// `fade', `moveIn', `push' and `reveal'. Defaults to `fade'
animation.type = kCATransitionReveal
// `fromLeft', `fromRight', `fromTop' and `fromBottom'
animation.subtype = kCATransitionFromTop
animation.isRemovedOnCompletion = true
animation.startProgress = 0.5
redView.layer.add(animation, forKey: nil)
第三方动画:Facebook POP
POP 是 Facebook 出品的一款很强大的动画引擎,使用简洁,效果非常不错
代码示例
if let anim = POPSpringAnimation(propertyNamed: kPOPLayerBounds) {
anim.toValue = NSValue(cgRect: CGRect(x: 0, y: 0, width: 400, height: 400))
layer.pop_add(anim, forKey: "size")
}
if let anim = POPBasicAnimation(propertyNamed: kPOPViewAlpha) {
anim.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
anim.fromValue = 0.0
anim.toValue = 1.0
view.pop_add(anim, forKey: "fade")
}
// .......