iOSUIKit动画从入门到放弃,简单易懂学习轻松容易掌握
动画 – UIKit
动画原理
- 视觉残留效应
- 运动模糊
做动画的时分要到达 60FPS 时分,画面才能流通,否则用户会感觉界面卡顿。
UIView 供给的动画支撑
UIView 动画本质上对 Core Animation 的封装,供给一个简练好用的动画接口,在要求不杂乱的情况下,完全能够完结许多动画。
UIView 动画能够设置的动画特点有:
- frame / bounds 大小改动
- center 中心方位
- transform 旋转平移等
- alpha 透明度
- backgroundColor 背景色彩
- contentStretch 拉伸内容
- Autolayout环境下的动画要直接修正constraint,留意 setNeedsUpdateConstraints,layoutIfNeeded的用法
UIView 类办法动画
-
动画的开端和完毕办法
-
UIView Block动画
-
Spring 动画
-
Keyframes 动画
-
转场动画
- 单个视图的过渡
- 从旧视图到新视图的过渡
1. 动画的开端和完毕办法
根本句子:
动画开端完毕标记
UIView.beginAnimations(String?, context: UnsafeMutablePointer<Void>)
第一个参数是动画标识,第二个参数是附加参数,在设置了署理的情况下,此参数将发送setAnimationWillStartSelector
和setAnimationDidStopSelector
所指定的办法,一般设为 nil。
UIView.commitAnimations()
动画完毕
动画参数设置办法
-
UIView.setAnimationDelay(NSTimeInterval)
设置动画的延时 -
UIView.setAnimationDuration(NSTimeInterval)
设置动画持续时刻 -
UIView.setAnimationDelegate(AnyObject?)
设置动画署理 -
UIView.setAnimationWillStartSelector(Selector)
设置动画即将开端时署理履行的SEL -
UIView.setAnimationDidStopSelector(Selector)
设置动画完毕时署理方针履行的SEL -
UIView.setAnimationRepeatCount(Float)
设置动画的重复次数 -
UIView.setAnimationCurve(UIViewAnimationCurve)
设置动画的曲线 -
UIView.setAnimationRepeatAutoreverses(Bool)
设置动画是否继续履行相反的动画 -
UIView.setAnimationsEnabled(Bool)
是否禁用动画作用(方针特点依然会被改动,只是没有动画作用) -
UIView.setAnimationBeginsFromCurrentState(Bool)
设置是否从当时状况开端播映动画- 假设上一个动画正在播映,且尚未播映完毕,咱们将要进行一个新的动画:
- 当为true时:动画将从上一个动画所在的状况开端播映
- 当为false时:动画将从上一个动画所指定的终究状况开端播映(此刻上一个动画马上完毕)
以下是简略的比如:
2. UIView Block 动画
1)最简略的 Block 动画包括时刻和动画
UIView.animateWithDuration(NSTimeInterval) { // 动画持续时刻
<#code#>//履行动画
}
2)带有动画完结回调的 Block 动画
UIView.animateWithDuration(NSTimeInterval, animations: {
<#code#>//履行动画
}) { (Bool) in
<#code#>// 动画完毕后履行的操作
}
3)能够设置推迟和过渡作用 Block 动画
UIView.animateWithDuration(NSTimeInterval, delay: NSTimeInterval, options: UIViewAnimationOptions, animations: {
<#code#>
}) { (<#Bool#>) in
<#code#>
}
留意,此处的 UIViewAnimationOptions 能够组合运用,在 swift 中写法options: [UIViewAnimationOptions.CurveEaseInOut, UIViewAnimationOptions.Repeat]
具体的枚举值,看官方文档即可。
4)Spring 动画
iOS7 后新增 Spring 动画,iOS 体系动画大部分采用 Spring Animation。
UIView.animateWithDuration(NSTimeInterval, delay: NSTimeInterval, usingSpringWithDamping: CGFloat, initialSpringVelocity: CGFloat, options: UIViewAnimationOptions, animations: {
<#code#>
}) { (<#Bool#>) in
<#code#>
}
- Duration: 动画持续时刻
- delay: 动画履行延时
- usingSpringWithDamping: 轰动作用,规模 0~1,数值越小,轰动作用越明显
- initialSpringVelocity: 初始速度
- options: 动画的过渡作用
5)Keyframes 关键帧动画
UIView.animateKeyframesWithDuration(NSTimeInterval, delay: NSTimeInterval, options: UIViewKeyframeAnimationOptions, animations: {
<#code#>
}) { (<#Bool#>) in
<#code#>
}
增加关键帧的办法
UIView.addKeyframeWithRelativeStartTime(Double, relativeDuration: Double, animations: {
<#code#>
})
留意开端时刻和持续时刻均是占总时刻的比例
UIViewKeyframeAnimationOptions 的枚举值如下,能够组合运用
UIViewAnimationOptionLayoutSubviews //进行动画时布局子控件
UIViewAnimationOptionAllowUserInteraction //进行动画时允许用户交互
UIViewAnimationOptionBeginFromCurrentState //从当时状况开端动画
UIViewAnimationOptionRepeat //无限重复履行动画
UIViewAnimationOptionAutoreverse //履行动画回路
UIViewAnimationOptionOverrideInheritedDuration //疏忽嵌套动画的履行时刻设置
UIViewAnimationOptionOverrideInheritedOptions //不承继父动画设置
UIViewKeyframeAnimationOptionCalculationModeLinear //运算形式 :连续
UIViewKeyframeAnimationOptionCalculationModeDiscrete //运算形式 :离散
UIViewKeyframeAnimationOptionCalculationModePaced //运算形式 :均匀履行
UIViewKeyframeAnimationOptionCalculationModeCubic //运算形式 :滑润
UIViewKeyframeAnimationOptionCalculationModeCubicPaced //运算形式 :滑润均匀
关键帧动画:
private func blockAni5() {
UIView.animateKeyframesWithDuration(5, delay: 0.0, options: UIViewKeyframeAnimationOptions.CalculationModeLinear, animations: {
UIView.addKeyframeWithRelativeStartTime(0, relativeDuration: 1.0/4, animations: {
self.greenView.backgroundColor = UIColor.redColor()
})
UIView.addKeyframeWithRelativeStartTime(1.0/4, relativeDuration: 1.0/4, animations: {
self.greenView.backgroundColor = UIColor.blackColor()
self.greenView.frame.size = CGSize(width: 50, height: 50)
})
UIView.addKeyframeWithRelativeStartTime(2.0/4, relativeDuration: 1.0/4, animations: {
self.greenView.backgroundColor = UIColor.yellowColor()
})
UIView.addKeyframeWithRelativeStartTime(3.0/4, relativeDuration: 1.0/4, animations: {
self.greenView.backgroundColor = UIColor.blueColor()
self.greenView.frame.size = CGSize(width: 250, height: 250)
})
}) { (_) in
print("动画完结blockAni5()")
}
}
简略的比如:
3. UIView 转场动画
在进行示例之前,咱们需要留意一点过渡改动动画与动画特点动画的不同之处。咱们在创立动画特点动画时只需要在animations闭包中增加对视图动画特点修正的代码即可,它没有作用域或作用视图的概念。而在过渡改动动画中有作用视图的概念,也便是说咱们调用过渡改动动画办法时需要指定一个作用视图
过渡改动动画中的作用视图并不是咱们的方针视图,而是方针视图的容器视图,那么咱们不难想象,假如该容器视图中有多个子视图,那么这些子视图都会有过渡改动动画作用。
1)从旧视图到新视图的转场
UIView.transitionFromView(UIView, toView: UIView, duration: NSTimeInterval, options: UIViewAnimationOptions) { (<#Bool#>) in
<#code#>
}
在该动画过程中,fromView 会从父视图中移除,并将 toView 增加到父视图中。转场动画的作用方针是父视图,过渡作用体现在父视图上
2)单个企图的过渡
UIView.transitionWithView(UIView, duration: NSTimeInterval, options: UIViewAnimationOptions, animations: {
<#code#>
}) { (<#Bool#>) in
<#code#>
}
简略的比如
中心动画 CoreAnimations
Core Animation(中心动画)是一组强壮的动画 API,是直接操作 CALayer 层来发生动画,相比上述的 UIView 动画,能够完结更杂乱的动画作用。
业务管理 CATransaction
CALayer 的可用于动画的特点成为 Animatable properties,苹果官方有具体的列表,显现了一切了能够动画的特点CALayer Animatable Properties。假如一个Layer方针对应着 View,则称这个 Layer 是一个 Root Layer, 非 Root Layer 一般是经过 CALayer 或许其子类直接创立的。
一切的非 Root Layer 在设置 Amimation Properties 的时分都存在隐式动画,默许的 duration 是0.25秒
业务(transaction)实际上是Core Animation用来包括一系列特点动画集合的机制,用指定业务去改动能够做动画的图层特点,不会马上发生改动,而是提交业务时用一个动画过渡到新值。任何 Layer 的可动画特点的设置都归于某个 CATransaction,业务的作用是为了确保多个特点的改动同时进行。业务能够嵌套,当业务嵌套时分,只要最外层的业务 commit 之后,整个动画才开端。
CATransaction没有任何实例办法,只要类型办法。CATransaction.begin()
和CATransaction.commit()
构成了一个动画块:
CATransaction.begin()
/* animation block */
CATransaction.commit()
其他的办法
func animationDuration() -> CFTimeInterval // get duration, defaults to 0.25s
func setAnimationDuration(dur: CFTimeInterval) // set duration
func animationTimingFunction() -> CAMediaTimingFunction? // get timing function
func setAnimationTimingFunction(function: CAMediaTimingFunction?) // set timing function
func disableActions() -> Bool // get disable actions state
func setDisableActions(flag: Bool) // set disable actions state
func completionBlock() -> (() -> Void)? // get completion block
func setCompletionBlock(block: (() -> Void)?) // set completion block
以上四组的办法能够用以下两个办法替代
func valueForKey(key: String) -> AnyObject?
func setValue(anObject: AnyObject?, forKey key: String)
CATransaction
动画块只能处理CALayer相关动画,无法正确处理UIView的动画,甚至UIView的 Root layer(与UIView相相关的CALayer)也不可。
UIView 的 Root layer动画为什么会在CATransaction动画块中失效?
隐式动画的查找过程如下:
制止隐式动画:
咱们把改动特点时CALayer自动运用的动画称作行为,当CALayer的特点被修正时分,它会调用-actionForKey:办法,传递特点的称号。剩下的操作都在CALayer的头文件中有具体的说明,实质上是如下几步:
- 图层首先检测它是否有托付,而且是否完结CALayerDelegate协议指定的-actionForLayer:forKey办法。假如有,直接调用并返回成果。
- 假如没有托付,或许托付没有完结-actionForLayer:forKey办法,图层接着查看包括特点称号对应行为映射的actions字典。
假如actions字典没有包括对应的特点,那么图层接着在它的style字典接着搜索特点名。
- 终究,假如在style里边也找不到对应的行为,那么图层将会直接调用界说了每个特点的规范行为的-defaultActionForKey:办法。
所以一轮完整的搜索完毕之后,-actionForKey:要么返回空(这种情况下将不会有动画发生),要么是CAAction协议对应的方针,终究CALayer拿这个成果去对先前和当时的值做动画。
于是这就解说了 UIKit 是怎么禁用隐式动画的:每个 UIView 对它相关的图层都扮演了一个托付,而且供给了
-actionForLayer:forKey
的完结办法。当不在一个动画块的完结中,UIView 对一切图层行为返回 nil,但是在动画 block 规模之内,它就返回了一个非空值。
- UIView相关的图层禁用了隐式动画,对这种图层做动画的仅有办法便是运用UIView的动画函数(而不是依赖CATransaction),或许承继UIView,并覆盖-actionForLayer:forKey:办法,或许直接创立一个显式动画。
- 对于独自存在的图层,咱们能够经过完结图层的-actionForLayer:forKey:托付办法,或许供给一个actions字典来操控隐式动画。
参考资料iOS Actions
时刻体系
参考谈谈 iOS Animation
CAMediaTiming
协议界说了在一段动画内用来操控逝去时刻的特点的集合。CALayer 经过CAMediaTiming
协议完结了一个有层级联系的时刻体系。
几个重要特点(都是CALayer的特点):
- beginTime 是相对于父级方针的开端时刻
- timeOffset是active local time的偏移量
- speed 设置当时方针的时刻消逝相对于父级方针时刻流的消逝速度
- fillMode 决定了当时方针过了非 active 时刻段的行为
显现动画
当需要对非 Root Layer 进行动画或许需要对动画做更多的自界说的行为的时分,需要运用显现动画,基类为CAAnimation
中心动画类中能够直接运用的类有:
- CABasicAnimation
- CAKeyframeAnimation
- CATransition
- CAAnimationGroup
- CASpringAnimation
CABasicAnimation有三个比较重要的特点,fromValue,toValue,byValue,这三个特点都是可选的,但不能同时多于两个为非空.终究都是为了确认animation改动的起点和终点.中间的值都是经过插值方式核算出来的.插值核算的成果由timingFunction指定,默许timingFunction为nil,会运用liner的,也便是改动是均匀的.
1. 中心动画类的中心办法
-
初始化CAAnimation方针
- 一般运用animation办法生成实例
let animation = CABasicAnimation()
- 假如是CAPropertyAnimation的子类,能够运用’let animation = CABasicAnimation(keyPath: String?)’来生成
- 一般运用animation办法生成实例
-
设置动画的相关特点
- 履行时刻
- 履行曲线
- keyPath 的方针值
- 署理等
animation.duration = 2.0
// animation.fromValue = UIColor.blackColor()
animation.toValue = NSValue(CGPoint: CGPointMake(300, 300))
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
animation.removedOnCompletion = false
animation.fillMode = kCAFillModeForwards
-
动画的增加和移除
- 调用 CALayer 的
view2.layer.addAnimation(animation, forKey: "color")
- 中止动画
view2.layer.removeAnimationForKey(String)
和view2.layer.removeAllAnimations()
- 调用 CALayer 的
防止动画完毕后回到初始状况
只需设置removedOnCompletion、fillMode两个特点就能够了。
transformAnima.removedOnCompletion = NO;
transformAnima.fillMode = kCAFillModeForwards;
解说:为什么动画完毕后返回原状况?
给一个视图增加layer动画时,真正移动并不是咱们的视图自身,而是 presentation layer 的一个缓存。动画开端时 presentation layer开端移动,原始layer躲藏,动画完毕时,presentation layer从屏幕上移除,原始layer显现。这就解说了为什么咱们的视图在动画完毕后又回到了本来的状况,由于它根本就没动过。
这个同样也能够解说为什么在动画移动过程中,咱们为何不能对其进行任何操作。
所以在咱们完结layer动画之后,最好将咱们的layer特点设置为咱们终究状况的特点,然后将presentation layer 移除掉。
2. 中心动画类的常用特点
- KeyPath:能够指定 KeyPath 为 CALayer 的特点值,并对它修正,留意部分特点是不支撑动画的
- duration:动画的持续时刻
- repeatCount: 动画的重复次数
- timingFunction:动画的时刻节奏操控
- fillMode:视图在非Active时的行为
- removedOnCompletion:动画履行完毕后是否从图层上移除,默许为YES(视图会康复到动画前的状况),可设置为NO(图层坚持动画履行后的状况,前提是fillMode设置为kCAFillModeForwards)
- beginTime:动画推迟履行时刻(经过CACurrentMediaTime() + your time 设置)
- delegate:署理
func animationDidStart(anim: CAAnimation)
func animationDidStop(anim: CAAnimation, finished flag: Bool)
Timing Function对应的类是CAMediaTimingFunction,它供给了两种取得时刻函数的方式,一种是运用预界说的五种时刻函数,一种是经过给点两个操控点得到一个时刻函数. 相关的办法为
CAMediaTimingFunction(name: String)
CAMediaTimingFunction(controlPoints: Float, c1y: Float, c2x: Float, c2y: Float)
五种预界说的时刻函数名字的常量变量分别为
- kCAMediaTimingFunctionLinear,
- kCAMediaTimingFunctionEaseIn,
- kCAMediaTimingFunctionEaseOut,
- kCAMediaTimingFunctionEaseInEaseOut,
- kCAMediaTimingFunctionDefault
自界说的 Timing Function 的函数图画便是一条三次的贝塞尔曲线。
CAKeyframeAnimation动画
两个决定动画关键帧的特点:
-
values: 关键帧数组方针,里边每一个元素便是一个关键帧,动画会在相应时刻段内,顺次履行数组中每一个关键帧动画
-
path: 动画路径方针,能够指定一个路径,在履行动画时会沿着路径移动,path只能对CALayer的 anchorPoint 和 position 特点起作用
-
keyTimes: 设置关键帧对应的时刻点。规模0 ~ 1,默许每一帧时刻平分,keyTimes数组中的每个元素界说了相应的keyframe的持续时刻值作为动画的总持续时刻的一小部分,每个元素的值有必要大于、或等于前一个值。
keyframeAni.keyTimes = [0.1,0.5,0.7,0.8,1]
-
calculationMode 核算形式,其主要针对的是每一帧的内容为一个座标点的情况,也便是对anchorPoint 和 position 进行的动画,表明插值核算的形式
- kCAAnimationLinear 默许值 直线相连来差值
- kCAAnimationDiscrete 离散的,不进行插值核算,一切关键帧逐个显现
- kCAAnimationPaced 动画均匀的,此刻keytimes和timeFunctions无效
- kCAAnimationCubic 对关键帧为坐标点的关键帧进行圆滑曲线相连后插值核算,对于曲线的形状还能够经过tensionValues,continuityValues,biasValues来进行调整自界说
- kCAAnimationCubicPaced 在kCAAnimationCubic的基础上使得动画运行变得均匀,便是体系时刻内运动的间隔相同,此刻keyTimes以及timingFunctions也是无效的.
简略比如
CATransition
转场动画,比 UIView 的转场动画具有更多的动画作用。
CATransition的特点:
-
type: 过渡动画的类型
- kCATransitionFade 渐变
- kCATransitionMoveIn 覆盖
- kCATransitionPush 推出
- kCATransitionReveal 揭开
私有动画类型的值有:”cube”、”suckEffect”、”oglFlip”、 “rippleEffect”、”pageCurl”、”pageUnCurl”等等
-
subtype: 过渡动画的方向
-
- kCATransitionFromRight 从右边
- kCATransitionFromLeft 从左面
-
- kCATransitionFromTop 从顶部
- kCATransitionFromBottom 从底部
CASpringAnimation
CASpringAnimation是iOS9新参加动画类型,是CABasicAnimation的子类,用于完结绷簧动画。
CASpringAnimation的重要特点:
- mass:质量(影响绷簧的惯性,质量越大,绷簧惯性越大,运动的幅度越大)
- stiffness:弹性系数(弹性系数越大,绷簧的运动越快)
- damping:阻尼系数(阻尼系数越大,绷簧的中止越快)
- initialVelocity:初始速率(绷簧动画的初始速度大小,绷簧运动的初始方向与初始速率的正负共同,若初始速率为0,表明疏忽该特点)
- settlingDuration:结算时刻(依据动画参数估算绷簧开端运动到中止的时刻,动画设置的时刻最好依据此刻间来设置)
private func springAni() {
let ani = CASpringAnimation(keyPath: "bounds")
ani.mass = 10.0 //质量,影响图层运动时的绷簧惯性,质量越大,绷簧拉伸和紧缩的幅度越大
ani.stiffness = 5000 //刚度系数(劲度系数/弹性系数),刚度系数越大,形变发生的力就越大,运动越快
ani.damping = 100.0//阻尼系数,阻止绷簧弹性的系数,阻尼系数越大,中止越快
ani.initialVelocity = 5.0//初始速率,动画视图的初始速度大小;速率为正数时,速度方向与运动方向共同,速率为负数时,速度方向与运动方向相反
ani.duration = ani.settlingDuration
ani.toValue = NSValue(CGRect: view4.bounds)
ani.removedOnCompletion = false
ani.fillMode = kCAFillModeForwards
ani.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
view2.layer.addAnimation(ani, forKey: "boundsAni")
}
运用Group能够将多个动画合并一同参加到层中,Group中一切动画并发履行,能够方便地完结需要多种类型动画的场景,group动画以数组表明。
private func groupAni() {
let posAni = CABasicAnimation(keyPath: "position")
posAni.toValue = NSValue(CGPoint: CGPoint(x: 310, y: 400))
let boundAni = CABasicAnimation(keyPath: "bounds")
boundAni.toValue = NSValue(CGRect: CGRectMake(0, 0, 200, 200))
let colorAni = CABasicAnimation(keyPath: "backgroundColor")
colorAni.toValue = UIColor.redColor().CGColor
let groupAni = CAAnimationGroup()
groupAni.animations = [posAni, boundAni, colorAni]
groupAni.duration = 1.5
groupAni.fillMode = kCAFillModeForwards
groupAni.removedOnCompletion = false
groupAni.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
view1.layer.addAnimation(groupAni, forKey: "groupAni")
}
文中demo的地址:Github动画demo