zoukankan      html  css  js  c++  java
  • 之一:CABasicAnimation

    嗷呜嗷呜嗷呜

    1 // 将视图作为属性方便后面执行多个不同动画
    2 _myView = [[UIView alloc] init];
    3 _myView.layer.position = CGPointMake(100, 100);
    4 _myView.layer.bounds = CGRectMake(0, 0, 100, 100);
    5 _myView.backgroundColor = [UIColor blueColor];
    6 [self.view addSubview:_myView];
    7 [_myView release];

     平移动画(1)

     1 // 创建一个CABasicAnimation类型的动画对象并对CALayer的position属性执行动画
     2 CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"position"];
     3 
     4 // 动画持续1.5s
     5 anim.duration = 1.5;
     6 
     7 // position属性值从(50, 80)渐变到(300, 350)
     8 anim.fromValue = [NSValue valueWithCGPoint:CGPointMake(50, 80)];
     9 anim.toValue = [NSValue valueWithCGPoint:CGPointMake(300, 350)];
    10 
    11 // 设置动画的代理
    12 anim.delegate = self;
    13 
    14 // 保持动画执行后的状态
    15 anim.removedOnCompletion = NO;
    16 anim.fillMode = kCAFillModeForwards;
    17 
    18 // 添加动画对象到myView的图层上
    19 [_myView.layer addAnimation:anim forKey:@"translate"];
    • 上面实现了平移动画
    • 想要实现不同的效果,最关键的地方就是第2行CABasicAnimation对象的初始化方法中keyPath的设定。必须是CALayer的某项属性。
    • 第8、9行这里的属性接收的是id类型的参数所以不能直接使用CGPoint这种结构体类型,而是要先包装成NSValue对象后再使用。
    • 注意:可以尝试将第9行的toValue换成byValue  区别:前者是到指定的位置,后者是在当前的位置上增加多少

    • 默认情况下,动画执行完毕后,动画会自动从CALayer上移除,CALayer又会回到原来的状态。为了保持动画执行后的状态,可以加入第15、16行代码

      fillMode的作用就是决定当前对象过了非active时间段的行为。比如动画开始之前,动画结束之后。如果是一个动画CAAnimation,则需要将其removedOnCompletion设置为NO,要不然fillMode不起作用.

      kCAFillModeRemoved 默认值 也就是说当动画开始前和动画结束后,动画对layer都没有影响,动画结束后,layer会恢复到之前的状态 
      kCAFillModeForwards 当动画结束后,layer会一直保持着动画最后的状态 
      kCAFillModeBackwards 这个和kCAFillModeForwards是相对的,就是在动画开始前,你只要将动画加入了一个layer,layer便立即进入动画的初始状态并等待动画开始.你可以这样设定测试代码,将一个动画加入一个layer的时候延迟5秒执行.然后就会发现在动画没有开始的时候,只要动画被加入了layer,layer便处于动画初始状态 
      kCAFillModeBoth 理解了上面两个,这个就很好理解了,这个其实就是上面两个的合成.动画加入后开始之前,layer便处于动画初始状态,动画结束后layer保持动画最后的状态.

    • 第19行后面的@"translate"只是给动画对象起了个名称,也可以直接给个nil,但是为方便以后可以调用CALayer的removeAnimationForKey:方法根据动画名称来移除相应的动画
    • 第12行后面的self是视图控制器。代理需要实现的方法:
     1 #pragma mark -----动画开始-----
     2 - (void)animationDidStart:(CAAnimation *)anim {
     3 NSLog(@"动画开始了");
     4 }
     5 
     6 #pragma mark -----动画结束-----
     7 - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
     8 // 查看一下动画执行完毕后的position值
     9 NSString *string = NSStringFromCGPoint(_myView.layer.position);
    10 NSLog(@"动画结束了,position:%@", string);
    11 }

    运行后发现, 在实质上,图层的属性值还是动画执行前的初始值,并没有真正被改变。

    1 // 移除动画
    2 [_myView.layer removeAnimationForKey:@"translate"]

    平移动画(2) 

    1 CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform"];
    2 anim.duration = 1;
    3 
    4 CATransform3D form = CATransform3DMakeTranslation(350, 350, 0);
    5 anim.toValue = [NSValue valueWithCATransform3D:form];
    6 
    7 [_myView.layer addAnimation:anim forKey:nil];
    • 通过CALayer的transform属性实现平移动画,layer会从自己的初始位置平移到(350, 350)位置
    • 通过transform(KVC)的方式来进行设置,可以简单实现3D效果的平移、缩放、旋转效果。
    • 可查看API文档搜索CABasicAnimation animationWithKeyPath Types

    缩放动画(1)

    1 CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"bounds"];
    2 anim.duration = 2;
    3 
    4 anim.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, 30, 30)];
    5 
    6 [_myView.layer addAnimation:anim forKey:nil];

    通过CALayer的bounds属性实现缩放动画,layer会从原来的尺寸(100x100)变为30x30

    缩放动画(2)

     1 CABasicAnimation *anim = [CABasicAnimation
     2 animationWithKeyPath:@"transform"];
     3 anim.duration = 1.5; // 动画持续1.5s
     4 
     5 // CALayer的宽度从0.5倍变为2倍
     6 // CALayer的高度从0.5倍变为1.5倍
     7 anim.fromValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.5, 0.5, 1)];
     8 anim.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(2, 1.5, 1)];
     9 
    10 [_myView.layer addAnimation:anim forKey:nil];

    旋转动画

    1 CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform"];
    2 anim.duration = 1.5;
    3 
    4 // 绕着(1, 1, 0)这个向量轴顺时针旋转45°
    5 anim.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI_4, 1, 1, 0)];
    6 
    7 [_myView.layer addAnimation:anim forKey:nil];
    • 提示:如果要仅需要图形以2D的方式旋转,只要把CATransform3DMakeRotation在z方向上的值改为1即可。

      anima.toValue=[NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI_4, 1, 1, 0)];

    • 通过以上可以发现其实可以不用设置fromValue,只设置了toValue
    • CABasicAnimation虽然能够做很多基本的动画效果,但是有个局限性,只能让CALayer的属性从某个值渐变到另一个值,仅仅是在2个值之间渐变
  • 相关阅读:
    《别闹了,费曼先生》听书笔记
    提升失败回报率的清单
    《真实的幸福》听书笔记
    JAVA好书之《深入理解Java虚拟机》
    2017第32周五
    2017第32周四
    《具身认知》听书笔记
    javascript的rsa加密和python的rsa解密
    python socket timeout设置
    想使用gevent、mysql、sqlalchemy实现python项目协程异步达到并发的效果
  • 原文地址:https://www.cnblogs.com/xs514521/p/5192378.html
Copyright © 2011-2022 走看看