转: iOS动画

iOS动画

原文连接: http://www.cnblogs.com/zzuliliu/p/5468732.htmlhtml

  本篇文章主要讲解iOS中动画的使用。spring

  一、Core Animation,核心动画。缓存

  核心动画执行过程都是在后台操做的,不会阻塞主线程。Core Animation是直接做用在CALayer上的,并不是UIView。post

  CAAnimation 是全部 Core Animation 动画类的父类,CAAnimation是一个抽象类,不能直接使用,应该使用它的子类。CAAnimation经常使用的子类有如下三个:动画

  CAPropertyAnimation,属性动画url

  CATransition,转场动画spa

  CAAnimationGroup,组动画线程

  其中,CAPropertyAnimation也是一个抽象类,咱们通常使用它的两个子类:code

  CABasicAnimation,基础动画,orm

  CAKeyframeAnimation,帧动画

  另外有一个协议:CAMediaTiming。

  1.一、CABasicAnimation,基础动画。经过上面的介绍,咱们能够知道,核心动画是做用在CALayer层,所以,基础动画是经过改变对象的layer的某个属性来实现动画效果的。至于CALayer的属性有哪些,你们能够自行看API,我这里仅就 position 属性来演示动画效果。下面看代码:

复制代码
 1 - (IBAction)CABasicAnimation:(UIButton *)sender {
 2     //参数须要是layer的属性,或者是属性的属性的名字
 3     CABasicAnimation *basic = [CABasicAnimation animationWithKeyPath:@"position.x"];
 4     basic.fromValue = @100;
 5     basic.toValue = @250;
 6     basic.duration = 3;
 7     basic.repeatCount = 1;
 8     //须要手动改变位置,(若是须要改变position的真实位置)
 9 //    self.redView.layer.position = CGPointMake(250, 100);
10     //key,标识
11     [self.redView.layer addAnimation:basic forKey:nil];
12 }
复制代码

  解释一下上面的代码,Line3中建立了一个动画,这个动画是改变 某个对象在x轴的位置,即 position.x 来实现的;Line4中制定了x的起始位置,Line5中指定了x的终止位置,Line6设置动画执行时间为3S,Line7设置动画重复次数为1,Line11中,将这个动画指定给 self.redView.layer 。

  当上面的动画执行完成后,咱们会发现,self.redView又回到了初始位置,也就是说,动画并不会真正改变layer的属性值。咱们能够经过Line9中的代码,来实际改变layer的属性值,让对象停留在终止位置。

  1.二、CAKeyframeAnimation,关键帧动画。这个和基础动画很相似,只不过是能够经过添加一组基础动画来执行,下面直接上代码,代码解释参考上面的:

复制代码
 1 //关键帧动画
 2 - (IBAction)keyFrameAnimation:(UIButton *)sender {
 3     
 4     CAKeyframeAnimation *keyFrameAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
 5     CGPoint point0 = CGPointMake(100, 100);
 6     CGPoint point1 = CGPointMake(100, 200);
 7     CGPoint point2 = CGPointMake(200, 200);
 8     CGPoint point3 = CGPointMake(200, 300);
 9     CGPoint point4 = CGPointMake(150, 300);
10     CGPoint point5 = CGPointMake(175, 250);
11     CGPoint point6 = CGPointMake(175, 100);
12     
13     NSValue *value1 = [NSValue valueWithCGPoint:point0];
14     NSValue *value2 = [NSValue valueWithCGPoint:point1];
15     NSValue *value3 = [NSValue valueWithCGPoint:point2];
16     NSValue *value4 = [NSValue valueWithCGPoint:point3];
17     NSValue *value5 = [NSValue valueWithCGPoint:point4];
18     NSValue *value6 = [NSValue valueWithCGPoint:point5];
19     NSValue *value7 = [NSValue valueWithCGPoint:point6];
20     
21     //根据一组点来建立动画
22     keyFrameAnimation.values = @[value1, value2, value3, value4, value5, value6, value7, value1];
23     keyFrameAnimation.duration = 10;
24     [self.redView.layer addAnimation:keyFrameAnimation forKey:nil];
25 }
复制代码

  上面的代码,你们能够自行建立一个View,即代码中的 self.redView,演示一下就明白了。

  1.3 CATransition转场动画。下面看代码:

复制代码
- (IBAction)transitionAnimation:(UIButton *)sender {
    
    CATransition *transition = [CATransition animation];
    transition.type = @"rippleEffect";  //动画过渡类型
    transition.subtype = kCATransitionFromLeft; //动画过分方向
    transition.repeatCount = HUGE_VALL; //动画重复次数,最大次数
    transition.duration = 2;    //动画持续时间
    [self.redView.layer addAnimation:transition forKey:nil];
}
复制代码

  下面我罗列了一些过渡类型,供你们参考使用:

复制代码
1      pageCurl            向上翻一页
2      pageUnCurl          向下翻一页
3      rippleEffect        滴水效果
4      suckEffect          收缩效果,如一块布被抽走
5      cube                立方体效果
6      oglFlip             上下翻转效果
复制代码

  1.4 CAAnimationGroup。组动画实际上就是能够将上面的几种动画类型随意组合添加到一个对象上。下面看代码:

复制代码
 1 - (IBAction)groupAnimation:(UIButton *)sender {
 2     //建立一个缩放动画
 3     CABasicAnimation *basic = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
 4     basic.fromValue = @1;
 5     basic.toValue = @0.75;
 6     //建立一个关键帧动画,从一个位置到另外一个位置
 7     CAKeyframeAnimation *keyFrameAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
 8     CGPoint point1 = CGPointMake(100, 100);
 9     CGPoint point2 = CGPointMake(300, 300);
10     NSValue *value1 = [NSValue valueWithCGPoint:point1];
11     NSValue *value2 = [NSValue valueWithCGPoint:point2];
12     keyFrameAnimation.values = @[value1, value2];
13     //建立一个动画组
14     CAAnimationGroup *group = [CAAnimationGroup animation];
15     group.duration = 4;
16     group.repeatCount = 3;
17     //将上面的两种动画添加到动画组中,动画将同步执行
18     [group setAnimations:@[basic,keyFrameAnimation]];
19     //下面的代码会最终改变对象的位置,不然对象在动画完成后会回到初始位置
20     self.redView.layer.position = CGPointMake(300, 300);
21     //添加动画组
22     [self.redView.layer addAnimation:group forKey:nil];
23 }
复制代码

  1.5 CASpringAnimation,弹簧动画,继承于CABasicAnimation。都不难,上代码吧:

复制代码
- (IBAction)springAnimation:(UIButton *)sender {
    
    CASpringAnimation *spring = [CASpringAnimation animationWithKeyPath:@"transform.rotation"];
    //质量越大,惯性越大
    spring.mass = 1;
    //阻尼系数,越大中止的越快
    spring.damping = 0.2;
    spring.fromValue = @0.2;//transform.rotation的初始值
    spring.toValue = @0.75;//transform.rotation的结束值
    spring.repeatCount = 1;
    spring.autoreverses = YES;//自动回弹
    //初始速度
    spring.initialVelocity = 5;
    spring.duration = spring.settlingDuration;
    [self.redView.layer addAnimation:spring forKey:@"spring"];
}
复制代码

  下面我总结了一下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
复制代码

  上面就是核心动画的所有内容了,基本就是以代码来说解,这些东西原理上没什么可说的,主要是知道怎么用。下面说说UIView动画。

  二、UIView动画。UIKit直接将动画集成到UIView类中,当内部的一些属性发生变化时,UIView将为这些改变提供动画支持。执行动画的工做由UIView类自动完成,但仍但愿在执行动画时通知视图,所以须要将改变属性的代码放在 [UIView beginAnimations:nil context:nil] 和 [UIView commitAnimations] 之间。

  通常来讲,可以影响控件外形的属性均可以使用动画,而UIView动画的实现由两种方式,咱们先看第一种方式,下面看代码,一个改变控件Frame的动画:

复制代码
 1 - (IBAction)changeFrame:(UIButton *)sender {
 2     //第一个参数,动画标示
 3     [UIView beginAnimations:@"changeFrame" context:nil];
 4     //设置动画次数
 5     [UIView setAnimationRepeatCount:100];
 6     //设置动画时长
 7     [UIView setAnimationDuration:1];
 8     //设置动画速率
 9     [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
10     CGRect frame = self.showView.frame;
11     frame.origin.y = 200;
12     //改变frame,y值
13     self.showView.frame = frame;
14     //开始动画
15     [UIView commitAnimations];
16 }
复制代码

  你们看注释应该能明白这段代码的意思。

  再上一段代码,缩放动画: 

复制代码
1 //缩放动画
2 - (IBAction)scaleButtonAction:(UIButton *)sender {
3     
4     [UIView beginAnimations:@"UIView" context:nil];
5     self.showView.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.5, 1.5);
6 }
复制代码

  旋转动画:

复制代码
 1 // 旋转
 2 - (IBAction)rotateButtonAction:(UIButton *)sender {
 3     [UIView beginAnimations:nil context:nil];
 4     // 第一个参数: 以谁为基准进行旋转
 5     // 第二个参数: 旋转的弧度
 6     // CGAffineTransformIdentity 原始形变
 7     [UIView setAnimationDuration:1];
 8     self.showView.transform = CGAffineTransformRotate(self.showView.transform, -M_PI / 180 * 30);
 9     [UIView commitAnimations];
10 }
复制代码

  咱们再来看一下另外一种方式实现的UIView动画。

  简单的Block动画:

复制代码
 1 // 简单block动画
 2 - (IBAction)simpleBlock:(UIButton *)sender{
 3     [UIView animateWithDuration:2 animations:^{
 4         CGPoint point = self.planeImageView.center;
 5         point.y += 100;
 6         self.planeImageView.center = point;
 7     } completion:^(BOOL finished) {
 8         NSLog(@"动画结束");
 9         [UIView animateWithDuration:2 animations:^{
10             CGPoint point = self.planeImageView.center;
11             point.y -= 100;
12             self.planeImageView.center = point;
13         } completion:nil];
14         
15     }];
16 }
复制代码

  复杂的Block动画:

复制代码
1 // 复杂的block
2 - (IBAction)complexBlock:(UIButton *)sender {
3     [UIView animateWithDuration:2 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
4         self.planeImageView.transform = CGAffineTransformRotate(self.planeImageView.transform, M_PI / 180 * 90);
5     } completion:^(BOOL finished) {
6         // 还原到初始形变
7 //        self.planeImageView.transform = CGAffineTransformIdentity;
8     }];
9 }
复制代码

  转场动画:

复制代码
 1 // 过分动画, 转场动画
 2 - (IBAction)transitionAnimation:(UIButton *)sender {
 3     [UIView beginAnimations:nil context:nil];
 4     [UIView setAnimationDuration:2];
 5     // 第一个参数: 转场动画的类型
 6     // 第二个参数: 给哪一个对象添加转场动画
 7     // 第三个参数: 缓存设置(YES执行效率更高)
 8     [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.label cache:YES];
 9     self.label.text = @"熊大熊二的故事";
10     [UIView commitAnimations];
11 }
复制代码

  弹簧动画:

复制代码
 1 // 弹簧动画
 2 - (IBAction)sprintAnimation:(UIButton *)sender {
 3     // 1. 动画时长
 4     // 2. 延迟时间
 5     // 3. 阻尼系数, 越大, 弹簧形变越小
 6     // 4. 速度
 7     // 5. 动画类型选项
 8     [UIView animateWithDuration:2 delay:0 usingSpringWithDamping:0.1 initialSpringVelocity:10 options:UIViewAnimationOptionCurveLinear animations:^{
 9         CGPoint point = self.planeImageView.center;
10         point.y += 260;
11         self.planeImageView.center = point;
12         
13     } completion:^(BOOL finished) {
14         NSLog(@"动画结束");
15     }];
16 }
复制代码

  你们能够发现,第二种实现方式其实是对第一种方式使用了Block封装,相对来讲,第二种实现方式更加的方便。而仔细看核心动画和UIView动画,咱们也能够发现,实际上,UIView动画就是对核心动画的封装,使用起来更加的方便。

相关文章
相关标签/搜索