iOS动画系列之七:实现相似Twitter的启动动画

来来来,今天我们经过实现一个相似Twitter的启动动画来看看CAKeyFrame Animation和CAAnimation Group怎么玩。git

因此今天我们的重点到了第七章,CAKeyFrame Animation和CAAnimation Group。最后的那个启动动画彻底是为了实践一下看看CAKeyFrame Animation和CAAnimation Group怎么使用。swift

有读者私下说更新速度太慢了。在码云上看了一下下载的统计,发现其实下载的童鞋并非特别多。若是只是看看思路,或者复习一下这些基础知识,确实是很快。可是若是对于这些内容不是特别熟悉,建议仍是敲一边代码,看看本身能碰到什么坑。bash

俺写一篇分享文章大约要4~6个小时,大致是三部分:想到合适的例子,敲代码写注释,写文章。一般都会看本身当前的状况,决定是先写swift版仍是OC版,而后不动脑子的翻译成另一版调整一下BUG。这样也是为了训练本身,前段时间发现本身有时候会不自觉的把两种语言混在一块儿,这个习惯特别很差,因此想用这种方式本身纠正一下。到最后更新写文章的时候反而更轻松了,由于不用动脑。哈哈~并发

Come on~下面这张图纯粹是为了简书看成封面使用的。也不知道为何,之前简书还能自动把GIF的第一桢看成封面,如今很差使了。app

CAKeyFrame Animation和CAAnimation Group.png
CAKeyFrame Animation和CAAnimation Group.png

下面展现一下写完以后的成果:布局

ani.gif
ani.gif

源代码能够在这里下载,里面有OC和Swift两版。git.oschina.net/atypical/CA…学习

iOS动画系列之CAKeyFrame Animation和CAAnimation Group(OC和Swift两版)动画

1. CAKeyframeAnimation

CAKeyframeAnimation是CApropertyAnimation的子类,跟CABasicAnimation的区别是:CABasicAnimation只能从一个数值(fromValue)变到另外一个数值(toValue),而CAKeyframeAnimation会使用一个NSArray保存这些数值。ui

建立步骤:spa

  1. 建立关键帧动画对象
  2. 设置属性
  3. 添加到要做用的layer上
  • 若是使用rect椭圆的方式,动画会不连贯,停顿一下。缘由是由于矩形的周长比椭圆的长,动画路径按照椭圆执行完以后,须要等待一下最大周长走完。
    这些都是由于计算模式致使的。

1.1 建立一个抖动的小方块

咱们用一个简单的demo来感觉一下CAKeyframeAnimation,来作一个会抖动的小方块。

抖动的小方块.gif
抖动的小方块.gif

CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"];
//设置一些列的关键帧动画
    animation.values = @[@(-M_PI_4 / 5),@(M_PI_4 / 5),@(-M_PI_4 / 5)];
    animation.repeatCount = CGFLOAT_MAX;
    [self.view.layer addAnimation:animation forKey:@"rotation"];复制代码

1.2 建立一个沿椭圆路径运动的小飞机

咱们建立一个UIBezierPath,让小飞机沿着这个路径运动。

//建立动画对象
    CAKeyframeAnimation *keyFrameAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
//设置属性:建立beziper路径,并把路径做为运动轨迹
    UIBezierPath *bezierPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(100, 100, 200, 500)];
    keyFrameAnimation.path = bezierPath.CGPath;
//设置动画时间
    keyFrameAnimation.duration = 2;
//设置动画循环播放的次数
    keyFrameAnimation.repeatCount = CGFLOAT_MAX;
//设置动画的计算模式
    keyFrameAnimation.calculationMode = kCAAnimationPaced;

//将动画添加到layer上
    [self.planeView.layer addAnimation:keyFrameAnimation forKey:nil];复制代码

1.3 动画叠加

刚才添加了一个沿路径运动的飞机,咱们同时还能够给飞机再把抖动的那个动画也添加上去。前几篇提到后面那个forKey,可能还有童鞋不知道干啥用。如今看到了木有?一个layer里面好几个动画,如何找到对应的动画吶?如今经过这个key就能找到了。

//        为小飞机同时添加抖动的动画和椭圆路径旋转的动画
    [self.planeImageView.layer addAnimation:[self shakeAni] forKey:nil];
    [self.planeImageView.layer addAnimation:[self ovalAni] forKey:nil];复制代码

2. CAAnimationGroup

单一的动画在实际中每每是不能知足需求的,这时就须要用到动画组。

  • 是CAAnimation的子类
  • 能够保存一组动画对象,将CAAnimationGroup对象加入图层后,组中全部动画对象能够同时并发运行.

咱们试着作一个包行旋转、缩放、按必定弧度路径组合在一块儿的动画。效果以下:

arcAni.gif
arcAni.gif

- (CAAnimationGroup *)groupAni{
    //        实例化一个组动画对象
        CAAnimationGroup *groupAni = [[CAAnimationGroup alloc] init];

    //        建立旋转的动画
        CABasicAnimation *basicRotation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    basicRotation.toValue = @(M_PI * 2);

    //        建立缩放的动画
        CABasicAnimation *basicScale = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
    basicScale.toValue = @(0.2);

    //        建立按照路径移动的动画
        CAKeyframeAnimation *keyFrameAni = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    UIBezierPath *arcPath = [UIBezierPath bezierPathWithArcCenter:self.view.center radius:150 startAngle:0 endAngle:M_PI * 2 clockwise:YES];

    keyFrameAni.path = arcPath.CGPath;
    keyFrameAni.calculationMode = kCAAnimationPaced;
    keyFrameAni.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

    //        将旋转、缩放、移动的动画添加到组动画中
    groupAni.animations = @[basicRotation,basicScale,keyFrameAni];
    //        组动画重复次数
        groupAni.repeatCount = CGFLOAT_MAX;
    //        组动画时长
        groupAni.duration = 2;

    return groupAni;
}复制代码

3. 实现相似Twitter的启动动画

3.1实现思路

1,在View上设置一个东西可以遮挡住背景图;
2,把遮罩变成五角星;
3,让遮罩慢慢变大,中间可见区域愈来愈大。

yes!思路就是这样的。那怎么遮住背景图片呢?

3.2 CALayer的遮罩属性

CALayer自己有一个属性,叫mask。咱们来看一下官方解释:

@property(nullable, strong) CALayer *mask;

When true an implicit mask matching the layer bounds is applied to
the layer (including the effects of the `cornerRadius' property). If both `mask' and `masksToBounds' are non-nil the two masks are multiplied to get the actual mask values. Defaults to NO. Animatable.复制代码

它相似于一个子图层,相对于父图层(即拥有该属性的图层)布局,可是它却不是一个普通的子图层。不一样于其余可以在父图层中绘制出图像的子图层,mask图层定义了父图层的部分可见区域。

mask图层的Color属性是可有可无的,真正重要的是图层的轮廓。也就是说mask图层实心的部分会被保留下来,其余的则会被抛弃。若是mask图层比父图层要小,只有在mask图层里面的内容才是它关心的,除此之外的一切都会被隐藏起来。

Paste_Image.png
Paste_Image.png

3.3 实现相似Twitter的启动动画

好了准备工做都作完了,咱们就开始写这个动画了。这个动画其实就是一个简单的CAKeyframeAnimation。设置了三个关键帧动画的大小,以及这三个关键帧的运动节奏。

而后,就好啦~而后,就好啦~而后,就好啦~而后,就好啦~

哪尼?!!!就这样?!!对啊,就这样。

- (CAKeyframeAnimation *)maskAni{
 //        放大缩小视图,keypath使用bounds
 CAKeyframeAnimation *maskAni = [CAKeyframeAnimation animationWithKeyPath:@"bounds"];
 //        动画时间
 maskAni.duration = 30.75;
 //        动画延迟0.5秒播放
 maskAni.beginTime = CACurrentMediaTime() + 0.5;


 //        设置关键帧动画的数值
 CGRect startRect = self.maskLayer.frame;

 CGRect tempRect = CGRectMake(0, 0, 100, 100);

 CGRect finalRect = CGRectMake(0, 0, 2000, 2000);
 maskAni.values = @[[NSValue valueWithCGRect:startRect],[NSValue valueWithCGRect:tempRect],[NSValue valueWithCGRect:finalRect]];


 //        设置关键帧动画的运动节奏
 maskAni.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut],[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];


 //        动画播放结束后是否移除动画
 maskAni.removedOnCompletion = NO;

 //        动画填充模式:kCAFillModeForwards:当动画结束后,layer会一直保持着动画最后的状态
 maskAni.fillMode = kCAFillModeForwards;

 return maskAni;


 }复制代码

留一个小问题

我在OC和Swift里面对不一样的View使用了mask。一个是给背景图片的UIImageView设置了mask,另外一个是直接给Controller的View设置了mask。设置这两个有神马区别咩?


好,下篇其实有一个重头,就是CAShapeLayer。由于在工做中碰到的大部分动画都是经过UIView的动画block实现,其余都基本上都是须要用到CAShapeLayer。咱们下次玩点好玩的吧~
若是还有兴趣,能够看看本系列的其余文章哈。

-----------------------华丽分割线,iOS动画系列全集连接-------------------------------------------------
第一篇:iOS动画系列之一:经过实战学习CALayer和透视的原理。作一个带时分秒指针的时钟动画(上)
第二篇:iOS动画系列之二:经过实战学习CALayer和透视的原理。作一个带时分秒指针的时钟动画。包含了OC和Swift两种源代码(下)
第三篇:iOS动画系列之三:Core Animation。介绍了Core Animation的经常使用属性和方法。
第四篇:CABasic Animation。iOS动画系列之四:基础动画之平移篇
第五篇:CABasic Animation。iOS动画系列之五:基础动画之缩放篇&旋转篇
第六篇:iOS动画系列之六:利用CABasic Animation完成带动画特效的登陆界面
第七篇:iOS动画系列之七:实现相似Twitter的启动动画
第八篇:iOS动画系列之八:使用CAShapeLayer绘画动态流量图
第九篇:iOS动画系列之九:实现点赞的动画及播放起伏指示器
第十篇:实战系列:绘制过山车场景

相关文章
相关标签/搜索