题记 :
在iOS开发中,我们往往能看到一些优美的交互体验,然后这些优美的交互体验往往离不开动画
在iOS实际开发中常用的动画一般有三种:UIView动画、核心动画、转场动画
iOS系统对动画实现的整体架构
在这里我们指讨论Core Animation和UIKit层的动画效果
1.UIKit动画
UIKit动画实质上是对coreAnimation的封装,提供简洁的动画接口,我们在开发中一般是来改动UIView的属性来实现动画效果,常用的属性有:
- frame
- bounds
- center
- transform
- alpha
- backgroundColor等
UIKit中执行动画的方法
常用方法:
• animateWithDuration:animations:
• animateWithDuration:animations:completion:
• animateWithDuration:delay:options:animations:completion:
其中:
withDuration:动画执行的时间
delay:在开始动画执行的时间
options:动画执行方式选项
animations:动画执行的block
completion:动画完成的回调
其他用法
1、关键帧动画
• animateKeyframesWithDuration:delay:options:animations:completion:
• addKeyframeWithRelativeStartTime:elativeDuration:animations:
其中:
frameStartTime 动画相对开始时间,取值为0-1.0
frameDuration 动画相对持续时间,取值为0-1.0
用例:
UIView.animateKeyframes(withDuration: 3, delay: 0, options: .calculationModePaced, animations: {
UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.2, animations: {
self.animationView.frame.origin.y = 500
})
UIView.addKeyframe(withRelativeStartTime: 0.2, relativeDuration: 0.5, animations: {
self.animationView.frame.origin.x = 300
})
UIView.addKeyframe(withRelativeStartTime: 0.7, relativeDuration: 0.3, animations: {
self.animationView.frame.origin.y = 300
})
}, completion: nil)
2、阻尼动画
UIView.animate(withDuration: , delay: , usingSpringWithDamping: , initialSpringVelocity: , options: , animations:, completion:)
其中
usingSpringWithDamping:当弹簧动画接近静止状态时的阻尼比
initialSpringVelocity:初始弹簧速度
用例:
UIView.animate(withDuration: 3, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations: {
self.animationView.frame.origin.x = 300
}, completion: nil)
3、Transitions过度动画
UIView.transition(from: , to: , duration: , options: , completion: )
其中
在动画过程中,首先将 fromView 从父视图中删除,然后将 toView 添加,就是做了一个替换操作
用例
UIView.transition(with: animationView, duration: 0.5, options: .transitionFlipFromLeft, animations: {
self.animationView.setNeedsDisplay()
}, completion: nil)
2. Core Animation核心动画
Core Animation核心动画主要来自定义layer的动画效果,因为view和layer紧密的关系,layer的变化会直接影响到viewCAAnimation-所有动画对象的父类
控制着动画的时间、转速、重复时间、重复次数等,它不能直接使用,应使用其具体的子类
一些重要的属性
- duration:动画的持续时间
- repeatCount:重复次数,无限循环可以设置HUGE_VALF或者MAXFLOAT
- repeatDuration:重复时间
- removedOnCompletion:默认为YES,代表动画执行完毕后就从图层上移除,图形会恢复到动画执行前的状态。如果想让图层保持显示动画执行后的状态,那就设置为NO,不过还要设置fillMode为kCAFillModeForwards
- fillMode:决定当前对象在非active时间段的行为。比如动画开始之前或者动画结束之后
- beginTime:可以用来设置动画延迟执行时间,若想延迟2s,就设置为CACurrentMediaTime()+2,CACurrentMediaTime()为图层的当前时间
- timingFunction:速度控制函数,控制动画运行的节奏
- delegate:动画代理
- timingFunction: 速度控制函数
CAPropertyAnimation
CAPropertyAnimation也是一个抽象的类,在创建动画时使用CABasicAnimation和CAKeyFrameAnimation两个子类
CABasicAnimation
两个重要的属性
fromeValue:kayPath对应的初始值
toValue:keyPath对应的结束值
CAKeyFrameAnimation
两个重要的属性
values:指定用于动画的关键帧值的对象数组
path:贝塞尔曲线
CAAnimationGroup
允许多个动画被分组并发运行
主要属性
animations:CAAnimation对象数组
CATransition
过度动画主要为图层不同状态之间变换提供动画效果
主要属性
type:设置动画的类型
subtype:设置动画的方向
粒子动画
粒子动画也是基于layer层的动画
主要的类:
CAEmitterLayer:粒子发射器
CAEmitterCell:粒子单元
CAEmitterLayer
CAEmitterLayer 是一个高性能的粒子引擎,被用来创建复杂的粒子动画如:烟雾,火,雨,雪花等效果,并且很好地控制了性能
官方的解释是:
CAEmitterLayer 看上去像是许多 CAEmitterCell 的容器,这些 CAEmitterCell 定义了一个例子效果。你将会为不同的例子效果定义一个或多个 CAEmitterCell 作为模版,同时 CAEmitterLayer 负责基于这些模版实例化一个粒子流。一个 CAEmitterCell 类似于一个 CALayer :它有一个 contents 属性可以定义为一个 CGImage ,另外还有一些可设置属性控制着表现和行为。
CAEmitterLayer本身不难,但由于其属性太多,因此在使用的时候可能会由许多困惑。下面就来解析一下它常用的属性
emitterPosition:粒子发射的位置
emitterSize:粒子的范围
emitterShape:粒子的形状
emitterDepth:粒子的深度
emitterMode:粒子发射的模式
CAEmitterCell
单个的粒子
常用属性
contents: 粒子的内容
birthRate:每秒释放多少个粒子
lifetime:每个粒子的生命周期
color:粒子的颜色
redRange,blueRange,greenRange,alphaRange:RGBA设置
velocity:重力加速度也就是物理里面G。
velocityRange:加速范围
emissionRange:下落是旋转的角度
scale:发射比例
alphaRange:透明度调整
spin:粒子的平均旋转速度
3.转场动画
转场定义:下一场景的视图替换当前场景的视图及相应的控制器的替换,表现为当前视图的消失和下一视图的出现。
而转场动画就是基于此而产生的动画
转场动画主要是实现五个转场协议
- 转场代理
- 动画控制器
- 交互控制器
- 转场环境
- 转场协调器
转场代理
在iOS中转场主要有三种方式push、model、UITabBarController子控制器的切换,所以转场代理也有三种
- UINavigationControllerDelegate UINavigationController的delegate属性遵守该协议,用于push和pop
- UITabBarControllerDelegate UITabBarController的delegate属性遵守该协议,用于TabBarController子控制器的切换
- UIViewControllerTransitioningDelegate UIViewController的delegate属性遵守该协议,用于present和dismiss
转场代理的代理方法都会返回动画控制器(UIViewControllerAnimatedTransitioning)或者交互控制器(UIViewControllerInteractiveTransitioning)
动画控制器用于非交互转场,交互控制器用于交互转场
动画控制器
是转场动画最重要的部分,主要负责添加视图以及执行动画;遵守
代理方法
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval
func animateTransition(using transitionContext: UIViewControllerContextTransitioning)
第一个代理方法是控制动画的时间
第二个代理方法是动画的具体实现
交互控制器
通过交互手段,通常是手势来驱动动画控制器来实现动画,时用户能够控制整个动画的过程,遵守
转场环境
提供转场中需要的数据;遵守
//提供了转场时的容器视图
func containerView() -> UIView?
//获取参与转场的控制器有, UITransitionContextFromViewControllerKey 和 UITransitionContextToViewControllerKey 两个 Key
func viewControllerForKey(_ key: String) -> UIViewController?
//获取参与转场的视图,有 UITransitionContextFromViewKey 和 UITransitionContextToViewKey 两个 Key
func viewForKey(_ key: String) -> UIView?
转场协调器
可在转场动画发生的同时并行执行其他的动画,其作用与其说协调不如说辅助,主要在 Modal 转场和交互转场取消时使用,其他时候很少用到;遵守
协议;由 UIKit 在转场时生成,UIViewController 在 iOS 7 中新增了方法transitionCoordinator()
返回一个遵守该协议的对象,且该方法只在该控制器处于转场过程中才返回一个此类对象,不参与转场时返回 nil
案例