Canoe

iOS核心动画实践七(显式动画)

2017.06.21

基础动画

CABasicAnimation继承于CAPropertyAnimation,CAPropertyAnimation继承于CAAnimation。

CAAnimation:
* 计时函数
* delegate
* removedOnCompletion

CAPropertyAnimation: CAAnimation
* keyPath

CABasicAnimation : CAPropertyAnimation
* fromValue  动画开始前属性的值
* toValue       动画结束之后的值
* byValue       动画执行过程中改变的值
需要注意的是,只需要指定toValue或者byValue就可以了,不需要两个都设置

关键帧动画

CAKeyframeAnimation: CAPropertyAnimation
* values  每一帧的值
* path   路径
* keyTimes 关键时间点
* rotationMode 根据动画曲线的切线自动旋转

CAKeyframeAnimation同样是CAPropertyAnimation的一个子类,它依然作用于单一的一个属性,但是和CABasicAnimation不一样的是,它不限制于设置一个起始和结束的值,而是可以根据一连串随意的值来做动画。

- (IBAction)changeColor
{
    //create a keyframe animation
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
    animation.keyPath = @"backgroundColor";
    animation.duration = 2.0;
    animation.values = @[
                         (__bridge id)[UIColor blueColor].CGColor,
                         (__bridge id)[UIColor redColor].CGColor,
                         (__bridge id)[UIColor greenColor].CGColor,
                         (__bridge id)[UIColor blueColor].CGColor ];
    //apply animation to layer
    [self.colorLayer addAnimation:animation forKey:nil];
}

虚拟属性

为了旋转图层,我们可以对transform.rotation关键路径应用动画,而不是transform本身.

//使用虚拟属性之前
CABasicAnimation *animation = [CABasicAnimation animation];
    animation.keyPath = @"transform";
    animation.duration = 2.0;
    animation.toValue = [NSValue valueWithCATransform3D: CATransform3DMakeRotation(M_PI, 0, 0, 1)];
    [shipLayer addAnimation:animation forKey:nil];

//使用虚拟属性之后
CABasicAnimation *animation = [CABasicAnimation animation];
    animation.keyPath = @"transform.rotation";
    animation.duration = 2.0;
    animation.byValue = @(M_PI * 2);
    [shipLayer addAnimation:animation forKey:nil];

使用transform.rotation的好处在于:

  • 我们可以不通过关键帧一步旋转多于180度的动画。
  • 可以用相对值而不是绝对值旋转(设置byValue而不是toValue)。
  • 可以不用创建CATransform3D,而是使用一个简单的数值来指定角度。
  • 不会和transform.position或者transform.scale冲突(同样是使用关键路径来做独立的动画属性)。

因为CATransform3D并不是一个对象,它实际上是一个结构体
,并不符合KVC的相关属性,transform.rotation实际上是一个layer用于处理动画变换的虚拟属性。
这个转换实际是由CAValueFunction来实现的。

动画组

CABaseAnimation和CAKeyframeAnimation仅仅作用于单独的属性,CAAnimationGroup可以把这些动画结合在一起。

CAAnimationGroup: CAAnimation
* animations

过渡动画

过渡动画并不像属性动画那样平滑地在两个值之间做动画,而是影响到整个图层的变化。过渡动画首先展示之前的图层外观,然后通过一个交换过渡到新的外观。

CATransition: CAAnimation
* type     fade,movein,push,reval
* subType  right,left,top,bottom

layer的content修改自带隐式过度动画。

-(void)testTransition
{
    UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    [self.view addSubview:button];
    button.backgroundColor = [UIColor redColor];
    
    [button addTarget:self action:@selector(transitionButtonClick:) forControlEvents:UIControlEventTouchUpInside];
}

-(void)transitionButtonClick:(UIButton *)button
{
    CATransition *transition = [CATransition animation];
    transition.type = kCATransitionFade;
    [button.layer addAnimation:transition forKey:nil];
    button.frame = CGRectMake(200, 200, 80, 80);
}

需要注意的是,在一开始对button的layer添加动画无效,需要在点击的时候添加才起作用。
UIView有提供一个简单的调用过渡动画的接口UIView +transitionFromView:toView:duration:options:completion:和+transitionWithView:duration:options:animations:。但是这里的可用的过渡选项和CATransition的type属性提供的常量完全不同。UIView过渡方法中options参数可以由如下常量指定:

UIViewAnimationOptionTransitionFlipFromLeft 
UIViewAnimationOptionTransitionFlipFromRight
UIViewAnimationOptionTransitionCurlUp 
UIViewAnimationOptionTransitionCurlDown
UIViewAnimationOptionTransitionCrossDissolve 
UIViewAnimationOptionTransitionFlipFromTop 
UIViewAnimationOptionTransitionFlipFromBottom

对图层树的动画

CATransition并不作用于指定的图层属性,就是说他是作用于整个图层的,对于图层的任何变化都可以按照他的type类型展示动画效果。
相对于基础属性动画而言,过渡动画不能准确的控制动画的变换位置和过程,只能指定一定的动画效果,当然也可以自定义过渡动画。
具体的使用tabbar切换的淡入淡出动画,以及layer切换动画等。对于那种不太好做平滑动画效果的属性使用CAtransition很方便。

在动画过程中取消动画

我们可以用-addAnimation:forKey:添加动画,然后用- (CAAnimation *)animationForKey:(NSString *)key;检索动画,但是并不支持在动画过程中修改动画,所以这个方法主要修改动画属性。
为了终止一个指定动画,我们可以调用下面两个方法:

- (void)removeAnimationForKey:(NSString *)key;
- (void)removeAllAnimations;

动画一旦移除,那么图层就会显示模型图层的值。一搬动画结束之后都会自动移除,除非设置removedOnCompletion为NO。意思是动画结束之后不移除,那么要么自己手动释放,要么图层被销毁。

小结

这一部分我们学习了常用的一些动画,其中包括CABaseAnimation基础属性动画,CAKeyframeAnimation关键帧动画,以及在设置动画属性的时候可以设置虚拟属性让动画更简单更不会冲突,然后还有CATransition过渡动画。以及动画组。

那么这么多的动画让我们选择,怎样根据我们的业务场景选择最优的动画呢?首先我们要明确每个动画的使用场景。

  • CABaseAnimation,一般简单用于layer的某一个属性从一个值到另一个确定的值。
  • CAKeyframeAnimation,一般是用于一个属性在一段时间内多次变化,相对于多次添加CABaseAnimation而言更加简便。
  • CAAnimationGroup,一般用于多个属性同时做动画效果,可以放在一个组里面,方便控制。
  • CATransition一般是用于不好控制动画效果的属性,比如View的切换,转场动画,image的切换等等,动画效果较为复杂炫酷,但是只有系统的预设几种,也可以自己定制,相对而言难度要高,并且不好精确的控制动画的每一个时间变换的效果。
Comments
Write a Comment