与动画有关的框架:
实现动画,可以使用最上层的UIKit,这个框架中的UIView类有许多与动画有关的方法。UIView的动画实现是基于Core Animation的。在UIView不能满足需求的时候,也可以直接使用Core Animation框架来实现动画。
一、可以作为动画元素的属性
动画的形成是通过在一定时间内不断改变视图的某个属性,以形成动起来的效果。对于不同的对象,可以作为动画元素的属性有些不一样。如下列出。
1、对于UIView
frame,bounds,center,alpha,backgroundColor,contentStretch,transform。
2、对于layer
位置、大小、动画的中心点,三维空间中的位移、layer自身的增删、在z轴上相对于其他layer的位置、阴影、边界的圆角效果、当大小被改变时被拉伸的部分、透明度、对于超出边界子layer的裁剪策略、当前内容、光栅部分。
UIView会有一个与之关联的layer,这个layer的属性是可以直接由UIVIew的方法改变。但是对于单独创建的layer(没有关联的UIView),要修改属性就必须要使用Core Animation。
这里特地了解下UIView的transform属性。
transform就是变幻,包括位置偏移,大小的变化和旋转。它的类型是CGAffineTransform,其实就是一个结构体,里面存的就是变幻的程度。我们使用这个属性来对视图进行变换的时候,不需要纠结这个结构体到底哪个量于哪个表示那种变换,如何给它赋值。有现成的方法可以方便地构造一个变换,或者给一个变换附加新的变换值。
要对视图进行变换,有两种思路:
一是通过现有方法构造一个结构体,然后赋给视图;二是先获取这个视图的transform属性,然后用现成的方法给它附加变换值,再将它赋给视图。下面说说这些现成的方法。
(1)现有的用来构造变换的方法:
构造具有偏移量tx,ty的变换(单位是屏幕点):
CGAffineTransform CGAffineTransformTranslate(CGAffineTransform t,CGFloat tx, CGFloat ty)
构造具有旋转角度angle的变换(角度,单位是弧度):
CGAffineTransform CGAffineTransformMakeRotation(CGFloat angle)
构造具有大小变换倍数sx,sy的变换:
CGAffineTransform CGAffineTransformMakeScale(CGFloat sx, CGFloat sy)
(2)现有的附加变换值的方法:
返回一个在变换t基础上附加了偏移量tx,ty的变换:
CGAffineTransform CGAffineTransformTranslate(CGAffineTransform t,CGFloat tx, CGFloat ty)
返回一个在变换t基础上附加了变换倍数sx,sy的变换:
CGAffineTransform CGAffineTransformScale(CGAffineTransform t,CGFloat sx, CGFloat sy)
返回一个在变换t基础上附加旋转角度angle的变换:
CGAffineTransform CGAffineTransformRotate(CGAffineTransform t,
CGFloat angle)
视图位置的偏移、扩大或者缩小,以及旋转,都是相对于视图的中心属性center的,如果设置了layer的anchorPoint属性的话,就是相对于anchorPoint的。
如果动态地设置一个视图的transform属性,效果就是这个视图瞬间变换。可以使用动画让视图渐变。
注:iOS 8.0以后,这个属性在自动布局下是没有作用的。
二、使用UIView实现动画
1、UIVIew提供了一个基本方法:实现自定义的动画效果
+ (void)animateWithDuration:(NSTimeInterval)duration
delay:(NSTimeInterval)delay
options:(UIViewAnimationOptions)options
animations:(void (^)(void))animations
completion:(void (^)(BOOL finished))completion
- (1)参数duration
动画持续的时长 - (2)参数delay
动画延时执行的时间 - (3)参数animations
参数animations是block类型的,在这个block里面写要进行的改变。比如:
[UIView animateWithDuration:1.0 animations:^{
firstView.alpha = 0.0;
secondView.alpha = 1.0;
}];
这个例子里(使用了一个更简洁的方法,但也是基于上面的基本方法的),就是在1秒内,把firstView的透明度从当前的渐变成0,把secondView的透明度从当前的渐变成1。这就相当于实现了两个view的动态转换了。
- (4)参数completion
参数completion也是block类型的,在里面写动画完毕后要做的处理。 - (5)参数options
options指的是对动画的一些设置选项,它的值是一个枚举类型,每个枚举值都与动画的某个属性有关(比如说动画进行的速度),对动画效果有很大的影响,来看看都有哪些可选项:
动画的常规属性选项(下面选项根据需求可不选、单选、或多选):
UIViewAnimationOptionLayoutSubviews 表示在动画过程中会进行子视图布局,也就是说让子视图跟着父视图一起进行动画
UIViewAnimationOptionAllowUserInteraction表示在动画过程中可以进行用户交互
UIViewAnimationOptionBeginFromCurrentState从当前值来开始动画
UIViewAnimationOptionRepeat 无限循环
UIViewAnimationOptionAutoreverse 指明动画无限循环的方式为,从头进行到尾,再由尾进行到头,无限循环(区别于每次都从头开始,没有从尾回来的循环方式)
动画的速度选项(必须四选一,如果不选,默认是第一个):
UIViewAnimationOptionCurveEaseInOut (默认的)
UIViewAnimationOptionCurveEaseIn
UIViewAnimationOptionCurveEaseOut
UIViewAnimationOptionCurveLinear
这里的in和out表示的是动画进行的开始阶段和临近结束阶段。ease表示减速。因此ease-in就是动画在开始阶段比较慢,然后逐渐加快。ease-out就是开始的时候快,然后逐渐减慢。ease -in-out就是动画的进行开始慢,中间加速,最后由减速。linear就是线性,也就是平均进行。
注:以上的选项适用于所有的有关动画的方法。在此基础上,还有一些选项是在特定场合才生效的。下面在不同的方法中会提出来。
2、动画的嵌套
动画是可以嵌套的,也就是说在animation block里面可以再次调用UIView的动画相关的方法。
嵌套动画和父动画是一起开始执行的,嵌套动画会继承父动画的选项。
但是要记得,使用动画的嵌套时,一定要给父动画的options中加入UIViewAnimationOptionAllowAnimatedContent选项,否则,所有嵌套动画的效果都会看不到。
这个选项的意思是允许内容也参与动画。如果不添加这个选项的话,会先对参与动画的视图进行截图,然后对截图的属性进行渐变来形成动画效果,也就是说,显示出来是这个截图的效果,而非视图本身的效果,此时任何对视图本身进行的改变都是看不到的。实际运行的效果就是,父动画完成后,相关属性瞬间变成嵌套动画最后一个时刻的值。
另外,如果嵌套动画不想使用从父动画继承到的动画选项,可以在options中添加以下选项:(可多选)
UIViewAnimationOptionOverrideInheritedDuration 忽略继承到的动画时间
UIViewAnimationOptionOverrideInheritedCurve 忽略继承到的动画速度设置
UIViewAnimationOptionOverrideInheritedOptions 忽略所有继承的选项
3、UIView提供的可以实现指定动画效果的方法
(1)方法一:可以实现视图的三维翻转或翻页动画
+ (void)transitionWithView:(UIView *)view
duration:(NSTimeInterval)duration
options:(UIViewAnimationOptions)options
animations:(void (^)(void))animations
completion:(void (^)(BOOL finished))completion
这个方法可以实现一个视图的三维动画,包括翻转效果和翻页效果。
参数view就是要参与动画的视图,其他参数和前面的方法的同名参数意义一致。animation参数可以是nil,这样就只有翻转或者翻页效果。参数options是动画的选项,这个方法可以使用的选项除了上面提到动画常规属性选项、动画速度选项外,还有多出了一个:三维动画效果选项。
三维动画效果选项(单选):
UIViewAnimationOptionTransitionNone默认的没有效果
UIViewAnimationOptionTransitionFlipFromLeft向左翻转
UIViewAnimationOptionTransitionFlipFromRight向右翻转
UIViewAnimationOptionTransitionCurlUp向上翻页
UIViewAnimationOptionTransitionCurlDown向下翻页
UIViewAnimationOptionTransitionFlipFromTop向上翻转
UIViewAnimationOptionTransitionFlipFromBottom向下翻转
Note:
视图的翻转和翻页效果是一个独立的动画,animation block里面的动画实际上是以嵌套动画的形式存在的,因此要记得给视图的翻转和翻页动画添加UIViewAnimationOptionAllowAnimatedContent选项,不然看到的就是,先完成翻转或翻页动画,然后瞬间变成了animation block里面定义的最终值。不理解可以试试。
(2)方法二:可以实现转场动画
+ (void)transitionFromView:(UIView *)fromView
toView:(UIView *)toView
duration:(NSTimeInterval)duration
options:(UIViewAnimationOptions)options
completion:(void (^)(BOOL finished))completion
转场动画也有特有的效果选项:(单选)
UIViewAnimationOptionShowHideTransitionViews
UIViewAnimationOptionTransitionCrossDissolve 从fromView转到toView,fromView透明度不断增加,toView透明度不断减小的转场效果
除了这两个可选项,方法一里面说到的三维动画效果选项在该方法也适用,但是效果不一样。在方法一中,三维动画效果是作用于指定视图的,在这里,如果添加了三维动画效果选项,则会将三维动画效果作用于整个controller的根视图。不妨试试。
(3)方法三:实现关键帧动画
+ (void)animateKeyframesWithDuration:(NSTimeInterval)duration
delay:(NSTimeInterval)delay
options:(UIViewKeyframeAnimationOptions)options
animations:(void (^)(void))animations
completion:(void (^)(BOOL finished))completion
首先得知道什么是关键帧动画。UIView的其他动画方法,都是了给出了属性的初始值(当前值)和最终值,然后由方法自动实现从初始值到最终值的渐变。而关键帧动画则需要给出每一帧的值,还要指定每一帧的持续时间。当然,相关属性值从上一帧到下一帧的转换也是渐变的。
那么在该方法中,参数duration依旧是整个动画的持续时间,delay、options、completion的意义也没变,就是animations中,需要通过多次调用一个方法来为关键帧动画添加帧。
这个方法是:
+ (void)addKeyframeWithRelativeStartTime:(double)frameStartTime
relativeDuration:(double)frameDuration
animations:(void (^)(void))animations
方法的参数frameStartTime,是该帧的开始时间,当然是相对整个动画时长的,因此取值范围是0到1。参数frameDuration是该帧的持续时间,也是相对的,取值范围也是0到1。animations里面就给出参与动画的属性在该帧的值。
(4)方法四:弹性动画效果
+ (void)animateWithDuration:(NSTimeInterval)duration
delay:(NSTimeInterval)delay
usingSpringWithDamping:(CGFloat)dampingRatio
initialSpringVelocity:(CGFloat)velocity
options:(UIViewAnimationOptions)options
animations:(void (^)(void))animations
completion:(void (^)(BOOL finished))completion
一般的动画效果是从初始值到最终值的渐变,而这个弹性动画效果,则是在动画持续时间内,让相关属性值在初始值和最终值之间震荡,震荡的幅度随着时间衰减,一次形成了类似有弹性的感觉。参数dampingRatio,就是震荡幅度的衰减率,指的是,每次震荡,幅度变成上次的多少倍,因此取值是在0到1之间。第一次震荡的幅度就是最终值减去初始值。如果衰减率是1的话,震一次便衰减没了,0的话就是没有衰减,从动画开始到结束都在初始值和最终值之间震荡。参数velocity指的是属性值的变化速度,也就是每秒钟,属性值的变化量,这个变化量是相对于最大震荡值的。速度越快,震荡次数越多。
三、使用CoreAnimation实现动画
。。。。。本来应该有内容的。。。下次再写