欢迎来到 IT实训基地-南通科迅教育
咨询电话:0513-81107100
iOS动画详解
2016/12/2
科迅教育
321
南通IT培训班效果怎么样

常见的iOS对动画的操作分为两类:

CALayer层的操作

UIView的操作

二者有何区别

UIView里面包含有一个CALayer层

UIView之所以能够在屏幕上显示出来,完全因为其内部拥有一个CALayer层

CALayer层的操作更底层更轻量级、性能更高。

UIView动画执行完毕之后不会反弹,而CALayer动画改变layer的状态位置,出现假象的改变,其实实际位置并没有改变

开发时如何选择二者:

每个UIView的操作其实是对CALayer层的封装,比较简单,优先选择UIView动画操作。

操作CALayer层更直接,能实现UIView所不能实现的功能UIView动画

UIView常用的一些方法

一、首尾式动画(经典的不能再经典啦)

?
1
2
3
4
5
6
7
8
9
<codeclass="language-[UIView beginAnimations:nil context:nil] ; hljs objectivec">   //需要执行动画的核心代码
     //设置动画执行时间
     [UIView setAnimationDuration:2.0];
     //设置代理
     [UIView setAnimationDelegate:self];
     //设置动画执行完毕调用的事件
     [UIView setAnimationDidStopSelector:@selector(didStopAnimation)];
    self.customView.center=CGPointMake(200,300);
    [UIView commitAnimations];</code>
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<codeclass="language-+ (void)setAnimationWillStartSelector:(SEL)selector   当动画即将开始时,执行delegate对象的selector,并且把beginAnimations:context:中传入的参数传进selector hljs objectivec">
+ (void)setAnimationDidStopSelector:(SEL)selector  当动画结束时,执行delegate对象的selector,并且把beginAnimations:context:中传入的参数传进selector
 
+ (void)setAnimationDuration:(NSTimeInterval)duration   动画的持续时间,秒为单位
 
+ (void)setAnimationDelay:(NSTimeInterval)delay  动画延迟delay秒后再开始
 
+ (void)setAnimationStartDate:(NSDate *)startDate   动画的开始时间,默认为now
 
+ (void)setAnimationCurve:(UIViewAnimationCurve)curve  动画的节奏控制
 
+ (void)setAnimationRepeatCount:(float)repeatCount  动画的重复次数
 
+ (void)setAnimationRepeatAutoreverses:(BOOL)repeatAutoreverses  如果设置为YES,代表动画每次重复执行的效果会跟上一次相反
 
+ (void)setAnimationTransition:(UIViewAnimationTransition)transition forView:(UIView *)view cache:(BOOL)cache  设置视图view的过渡效果, transition指定过渡类型, cache设置YES代表使用视图缓存,性能较好
 
+ (void)setAnimationDelegate:(id)delegate     设置动画代理对象,当动画开始或者结束时会发消息给代理对象
 
+ (void)setAnimationWillStartSelector:(SEL)selector   当动画即将开始时,执行delegate对象的selector,并且把beginAnimations:context:中传入的参数传进selector
 
+ (void)setAnimationDidStopSelector:(SEL)selector  当动画结束时,执行delegate对象的selector,并且把beginAnimations:context:中传入的参数传进selector
 
+ (void)setAnimationDuration:(NSTimeInterval)duration   动画的持续时间,秒为单位
 
+ (void)setAnimationDelay:(NSTimeInterval)delay  动画延迟delay秒后再开始
 
+ (void)setAnimationStartDate:(NSDate *)startDate   动画的开始时间,默认为now
 
+ (void)setAnimationCurve:(UIViewAnimationCurve)curve  动画的节奏控制
 
+ (void)setAnimationRepeatCount:(float)repeatCount  动画的重复次数
 
+ (void)setAnimationRepeatAutoreverses:(BOOL)repeatAutoreverses  如果设置为YES,代表动画每次重复执行的效果会跟上一次相反
 
+ (void)setAnimationTransition:(UIViewAnimationTransition)transition forView:(UIView *)view cache:(BOOL)cache  设置视图view的过渡效果, transition指定过渡类型, cache设置YES代表使用视图缓存,性能较好</code>

二、block动画(依旧也经典)

?
1
2
3
4
5
6
7
<codeclass="hljs objectivec">+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void(^)(void))animations completion:(void(^)(BOOL finished))completion
 
//duration:动画的持续时间
//delay:动画延迟delay秒后开始
//options:动画的节奏控制
//animations:将改变视图属性的代码放在这个block中
//completion:动画结束后,会自动调用这个block</code>
?
1
2
3
4
5
6
7
<codeclass="hljs objectivec">+ (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void(^)(void))animations completion:(void(^)(BOOL finished))completion
 
//duration:动画的持续时间
//view:需要进行转场动画的视图
//options:转场动画的类型
//animations:将改变视图属性的代码放在这个block中
//completion:动画结束后,会自动调用这个block</code>
?
1
2
3
4
5
6
7
8
9
<codeclass="hljs objectivec">+ (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void(^)(BOOL finished))completion
 
//duration:动画的持续时间
 
//options:转场动画的类型
 
//animations:将改变视图属性的代码放在这个block中
 
//completion:动画结束后,会自动调用这个block</code>
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<codeclass="hljs ruby">options参数的详细的枚举
 
typedef NS_OPTIONS(NSUInteger, UIViewAnimationOptions) {
    UIViewAnimationOptionLayoutSubviews            =1<< 0,
    UIViewAnimationOptionAllowUserInteraction      =1<< 1,// turn on user interaction while animating
    UIViewAnimationOptionBeginFromCurrentState     =1<< 2,// start all views from current value, not initial value
    UIViewAnimationOptionRepeat                    =1<< 3,// repeat animation indefinitely
    UIViewAnimationOptionAutoreverse               =1<< 4,// if repeat, run animation back and forth
    UIViewAnimationOptionOverrideInheritedDuration =1<< 5,// ignore nested duration
    UIViewAnimationOptionOverrideInheritedCurve    =1<< 6,// ignore nested curve
    UIViewAnimationOptionAllowAnimatedContent      =1<< 7,// animate contents (applies to transitions only)
    UIViewAnimationOptionShowHideTransitionViews   =1<< 8,// flip to/from hidden state instead of adding/removing
    UIViewAnimationOptionOverrideInheritedOptions  =1<< 9,// do not inherit any options or animation type
 
    UIViewAnimationOptionCurveEaseInOut            =0<<16,// default
    UIViewAnimationOptionCurveEaseIn               =1<<16,
    UIViewAnimationOptionCurveEaseOut              =2<<16,
    UIViewAnimationOptionCurveLinear               =3<<16,
 
    UIViewAnimationOptionTransitionNone            =0<<20,// default
    UIViewAnimationOptionTransitionFlipFromLeft    =1<<20,
    UIViewAnimationOptionTransitionFlipFromRight   =2<<20,
    UIViewAnimationOptionTransitionCurlUp          =3<<20,
    UIViewAnimationOptionTransitionCurlDown        =4<<20,
    UIViewAnimationOptionTransitionCrossDissolve   =5<<20,
    UIViewAnimationOptionTransitionFlipFromTop     =6<<20,
    UIViewAnimationOptionTransitionFlipFromBottom  =7<<20,
} NS_ENUM_AVAILABLE_IOS(4_0);
</code>

CALayer层动画

CALayer的两个属性:

position位置(原点为父类的(0,0))

anchorPoint 锚点(默认原点在自身长和宽各一半的交点(0.5,0.5))

什么是隐式动画

简单说,每个控件都有一个自带的CALayer层,这个层称为根层,与之相对于的就是非根层,非根层的的属性改变就会默认引发动画,这样的动画就可以称为隐式动画

?
1
2
<code>若项目需求要求不能够动画效果,如何关闭隐式动画?
</code>
?
1
2
3
4
5
<codeclass="hljs sql">    [CATransaction begin];
    [CATransaction setDisableActions:YES];
    //......这里修改你想修改的Layer属性就不会产生默认的隐式动画
    [CATransaction commit];
</code>

Layer层的动画分类

 

这里写图片描述


 

CAAnimation是所有动画类的父类,它和CAPropertyAnimation不能直接使用,应该使用它的子类CABasicAnimation、CAKeyframeAnimation、CATransition、CAAnimationGroup

?
1
2
3
4
5
6
7
8
9
<codeclass="hljs ">CABasicAnimation基础动画
 
fromValue:keyPath相应属性值的初始值
 
toValue:keyPath相应属性的结束值
 
byValue : 增加多少值(注意对比toValue的意思)
 
keyPath内容是CALayer的可动画Animation属性</code>
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<codeclass="hljs avrasm">/*这是 keyPath 所有属性字符,供大家参考*/
    transform.scale = 比例轉換
 
    transform.scale.x = 闊的比例轉換
 
    transform.scale.y = 高的比例轉換
 
    transform.rotation.z = 平面圖的旋轉
 
    opacity = 透明度
 
    margin
 
    zPosition
 
    backgroundColor    背景颜色
 
    cornerRadius    圆角
 
    borderWidth
 
    bounds
 
    contents
 
    contentsRect
 
    cornerRadius
 
    frame
 
    hidden
 
    mask
 
    masksToBounds
 
    opacity
 
    position
 
    shadowColor
 
    shadowOffset
 
    shadowOpacity
 
    shadowRadius</code>
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<codeclass="hljs objectivec">// 1.创建动画对象
    CABasicAnimation *anim = [CABasicAnimation animation];
 
    // 2.设置动画对象
    // keyPath决定了执行怎样的动画, 调整哪个属性来执行动画
    anim.keyPath = @"transform.translation.x";
    anim.toValue = @(100);
    //执行的时间
    anim.duration =2.0;
    //加入下面两行,当动画结束时,layer所在的位置不会回到初始位置
    anim.removedOnCompletion = NO;
    anim.fillMode = kCAFillModeForwards;
     // 3.添加动画
    [self.layer addAnimation:anim forKey:nil];</code>

CAKeyframeAnimation关键帧动画

CAKeyframeAnimation是CABasicAnimation的升级版,CABasicAnimation只能改变一组属性动画就停止了,而CAKeyframeAnimation可以运行关于一个属性的一个数组的数据(这里需要特别注意是同一个属性的一组数据)

?
1
2
3
4
5
<codeclass="hljs cs">//values:所有的值
 
//path:路线
 
//keyTimes:可以为对应的关键帧制定对应的时间点,取值范围是0到1.0</code>

注意:path和values二者是相互排斥的,二者选取一个即可

?
1
2
3
4
5
6
7
8
9
10
11
12
<codeclass="hljs avrasm">/*values例子*/
 
        CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];
        anim.keyPath = @"transform.rotation";
        anim.values = array;
        anim.duration =0.25;
        // 动画的重复执行次数
        anim.repeatCount = MAXFLOAT;
        // 保持动画执行完毕后的状态
        anim.removedOnCompletion = NO;
        anim.fillMode = kCAFillModeForwards;
        [self.redView.layer addAnimation:anim forKey:nil];</code>
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<codeclass="hljs avrasm">/*path例子*/
 
CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];
 
    anim.keyPath = @"position";
    anim.removedOnCompletion = NO;
    anim.fillMode = kCAFillModeForwards;
    anim.duration =2.0;
 
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddEllipseInRect(path, NULL, CGRectMake(100,100,200,200));
    anim.path = path;
    CGPathRelease(path);
    /*设置动画的执行节奏*/
    anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    anim.delegate = self;
 
    [self.redView.layer addAnimation:anim forKey:nil];</code>

CAAnimationGroup 动画组

我们上面两个动画类都是只能对同一个属性进行修改产生动画,而不能同时修改两个参数属性。所有就引入了CAAnimationGroup动画组
最经典的莫过于:边旋转边缩放边移动的动画效果,其实就是前面的基础动画加入到动画组形成的

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<codeclass="hljs avrasm">   /*1.创建旋转动画对象*/
    CABasicAnimation *rotate = [CABasicAnimation animation];
    rotate.keyPath = @"transform.rotation";
    rotate.toValue = @(M_PI);
 
    /*2.创建缩放动画对象*/
    CABasicAnimation *scale = [CABasicAnimation animation];
    scale.keyPath = @"transform.scale";
    scale.toValue = @(0.0);
 
    /*3.平移动画*/
    CABasicAnimation *move = [CABasicAnimation animation];
    move.keyPath = @"transform.translation";
    move.toValue = [NSValue valueWithCGPoint:CGPointMake(100,100)];
 
    /*4.将所有的动画添加到动画组中*/
    CAAnimationGroup *group = [CAAnimationGroup animation];
    group.animations = @[rotate, scale, move];
    group.duration =2.0;
    group.removedOnCompletion = NO;
    group.fillMode = kCAFillModeForwards;
 
    [self.myvie.layer addAnimation:group forKey:nil];  </code>

CATransition转场动画

提供移除屏幕和移入屏幕的动画效果

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<codeclass="language-OC hljs scala">  /** 转场动画代码 */
    // 创建转场动画对象
    CATransition *anim = [CATransition animation];
 
    // 设置转场类型
    anim.type = @"pageCurl";
 
    // 设置动画的方向
    anim.subtype = kCATransitionFromLeft;
 
    anim.duration =3;
 
    [_imageV.layer addAnimation:anim forKey:nil];
 
//type:动画过渡类型
//subtype:动画过渡方向</code>

附一张type参照表

这里写图片描述


?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<codeclass="hljs objectivec">+(void)transitionWithView:(UIView*)view duration:(NSTimeInterval)duration options:
(UIViewAnimationOptions)options
animations:(void(^)(void))animations
completion:(void(^)(BOOLfinished))completion;
 
//duration:动画的持续时间
//view:需要进行转场动画的视图
//options:转场动画的类型
//animations:将改变视图属性的代码放在这个block中
//completion:动画结束后,会自动调用这个block
 
 
+ (void)transitionFromView:(UIView*) fromView
toView:(UIView*) toViewduration:(NSTimeInterval)durationoptions:(UIViewAnimationOptions) options
completion:(void(^)(BOOLfinished))completion;
 
//duration:动画的持续时间
//options:转场动画的类型
//animations:将改变视图属性的代码放在这个block中
//completion:动画结束后,会自动调用这个block</code>

动画代理

动画也是存在代理的,实现代理可以在动画开始的时候调用和动画结束的时候调用的时候做些事情

?
1
2
3
4
5
6
7
8
9
10
11
12
<codeclass="hljs cs"> anim.delegate = self;
 #pragma mark 动画开始的时候调用
- (void)animationDidStart:(CAAnimation *)anim
{
 
}
 
#pragma mark 动画结束的时候调用
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
 
}</code>
77
关闭
先学习,后交费申请表
每期5位名额
在线咨询
免费电话
QQ联系
先学习,后交费
TOP
您好,您想咨询哪门课程呢?
关于我们
机构简介
官方资讯
地理位置
联系我们
0513-91107100
周一至周六     8:30-21:00
微信扫我送教程
手机端访问
南通科迅教育信息咨询有限公司     苏ICP备15009282号     联系地址:江苏省南通市人民中路23-6号新亚大厦三楼             法律顾问:江苏瑞慈律师事务所     Copyright 2008-