Objective-C,从0开始写一个自定义加载动画

今天在精选 20 个优质的加载动画中发现了一个蛮有意思的加载动画:

效果图

正好最近原来的加载动画用的腻了😄
所以决定用OC实现一下这个动画来用看看。
那么我们开始

首先,分析一下这个动画:

1.元素分析

从gif上看,主体由一个盒子(三角形的洞)和一些飘落的元素组成(下方的字表示😢)。

2.动画分析

我们看到飘落的字从红框的位置随机出现,然后落向黄线的随机位置消失,同时透明度也从0开始变成1。

分析图

动画过程中,伴随着不同的角速度进行旋转,下落的速度也各不相同。
因此我们需要准备以下几个方法来实现动画效果:
1.产生随机的起点坐标
2.产生随机的终点坐标
3.产生随机的速度、角速度
4.实现位移、旋转、透明度改变的动画
从上面的分析来看,要实现这个效果并不是很困难😳。
So,Les's do it.

3.需要用到的知识储备

Core Animation
然后...嗯...貌似就够了...

4.代码实现

1.随机产生起点和终点坐标

//获取起点坐标
- (CGPoint)randomBeginPoint{
    return [self getRandomFrameInRect:CGRectMake(0, 0, self.frame.size.width, 10)];
}

//获取终点坐标
- (CGPoint)randomEndPoint{
    return [self getRandomFrameInRect:CGRectMake(0, self.frame.size.height - 20, self.frame.size.width, 10)];
}

//方形区域内产生随机点
- (CGPoint)getRandomFrameInRect:(CGRect)rect{
    CGFloat minX = rect.origin.x;
    CGFloat width = rect.size.width;
    CGFloat minY = rect.origin.y;
    CGFloat height = rect.size.height;
    //产生随机数
    CGFloat randomX = minX + (float)(arc4random() % (int)width);
    CGFloat randomY = minY + (float)(arc4random() % (int)height);
    return CGPointMake(randomX, randomY);
}

2.产生随机的角速度与下落速度
下落速度:通过下落到终点所需时间(即动画时间)设定
角速度:下落到终点时旋转的角度 和 动画时间 共同决定旋转的角速度

//获取随机的动画时间
- (CGFloat)getRandomDuration{
    //产生随机数(这里我们定义的动画时间为0.5s~1.0s)
    int time = arc4random()%50 + 50;
    CGFloat duration = time/100;
    return duration;
}

//获取随机的角度
- (CGFloat)getRandomRotation{
    //产生随机数(这里我们定义的旋转角度范围为 -180度~180度)
    int angle = arc4random()%360 - 180;
    CGFloat rotation = angle*180/M_PI;
    return rotation;
}

3.产生动画的方法

- (void)addAnimationToLayer:(CALayer*)layer{
    //获取随机参数
    CGFloat duration = [self getRandomDuration];
    CGFloat rotation = [self getRandomRotation];
    CGPoint beginPoint = [self getRandomBeginPoint];
    CGPoint endPoint = [self getRandomEndPoint];
    
    //平移
    CABasicAnimation *positionAnim = [CABasicAnimation animationWithKeyPath:@"position"];
    positionAnim.duration = duration;
    positionAnim.fromValue = [NSValue valueWithCGPoint:beginPoint];
    positionAnim.toValue = [NSValue valueWithCGPoint:endPoint];
    positionAnim.fillMode = kCAFillModeForwards;
    
    //旋转
    CABasicAnimation *transformAnim = [CABasicAnimation animationWithKeyPath:@"transform"];
    transformAnim.duration = duration;
    // 绕着(0, 0, 1)这个向量轴顺时针旋转rotation
    transformAnim.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(rotation, 0, 0, 1)];
    
    //透明度
    CABasicAnimation *opacityAnimation =[CABasicAnimation animationWithKeyPath:@"opacity"];
    opacityAnimation.fromValue = @0.f;
    opacityAnimation.toValue = @1.f;
    opacityAnimation.duration = duration;
    opacityAnimation.fillMode = kCAFillModeForwards;
    
    [layer addAnimation:positionAnim forKey:@"lposition"];
    [layer addAnimation:transformAnim forKey:@"ltransform"];
    [layer addAnimation:opacityAnimation forKey:@"lopacity"];
    layer.opacity = 0;

    //循环动画
    if (animation) {
        [self performSelector:@selector(addAnimationToLayer:) withObject:layer afterDelay:duration];
    }
}

4.测试一下动画的效果

UILabel *label = [[UILabel alloc]init];
label.text = @"0";
label.font = [UIFont systemFontOfSize:20];
label.textColor = [UIColor whiteColor];
[label sizeToFit];
[self addSubview:label];
[self addAnimationToLayer:label.layer];

5.循环动画
增加一个属性animation来判断是否循环执行动画(这样如果要停止循环只要把它设置为NO就好了),然后在addAnimationToLayer:添加循环调用的方法:

//循环动画
    if (_animation) {
        [self performSelector:@selector(addAnimationToLayer:) withObject:layer afterDelay:duration];
    }

6.添加细节
经过上面的过程,动画的效果已经解决了。
接下来就是产生4个元素,再加上下面终点的图片,基本上就可以达到想要的效果了。
上图:


效果图

好了 今天先实现到这里,后续有空到话再继续优化,代码已经上传到GZCLoding,如果有什么建议,欢迎留言告诉我哦。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,165评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,503评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,295评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,589评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,439评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,342评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,749评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,397评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,700评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,740评论 2 313
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,523评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,364评论 3 314
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,755评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,024评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,297评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,721评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,918评论 2 336

推荐阅读更多精彩内容

  • 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌。在这里你可以看...
    F麦子阅读 5,075评论 5 13
  • 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥ios动画全貌。在这里你可以看...
    每天刷两次牙阅读 8,429评论 6 30
  • 概览 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌。在这里你...
    被吹落的风阅读 1,540评论 1 2
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,952评论 4 60