iOS动画之大雪纷飞

来源:互联网 发布:剪切合并音乐软件 编辑:程序博客网 时间:2024/04/29 05:18

1.结果展示

美丽的雪花,勾起了多少骚年美好的回忆。^_^
这里写图片描述

2.制作思路

其实创作这样一个大学纷飞的场景是十分简单的,简单到你看了教程之后想不会都不行。OK,下面国际惯例,讲解一下思路吧。

1.创建一个数组用来保存大量的雪花

    _imagesArray = [[NSMutableArray alloc] init];    for (int i = 0; i < 1000; ++ i) {        UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"snow"]];        float x = IMAGE_WIDTH;        imageView.frame = CGRectMake(IMAGE_X, -30, x, x);        imageView.alpha = IMAGE_ALPHA;        [self.view addSubview:imageView];        [_imagesArray addObject:imageView];    }

2.使用时钟(CADisplayLink)来控制下雪,为什么不使用NSTimer呢。其实是可以的,只是(CADisplayLink)刷帧更快一些。

    //创建时钟,并且添加到主循环中    CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(makeSnow)];    [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];

3.下雪,就是把数组当做队列来使用。

  1. 每次从数组头部取出一个雪花并且删除其在数组中的占位。
  2. 让雪花飘落,通过UIView动画完成frame,transform等改变。
  3. 当动画完成之后,将取出的雪花再次放进数组的尾部
- (void)makeSnow{    if (_imagesArray.count > 0) {        UIImageView *imageView = _imagesArray[0];        [_imagesArray removeObjectAtIndex:0];        [self snowFall:imageView];    }}- (void)snowFall:(UIImageView *)imageView{    [UIView animateWithDuration:10 animations:^{        imageView.frame = CGRectMake(imageView.frame.origin.x, Main_Screen_Height, imageView.frame.size.width, imageView.frame.size.height);        imageView.transform = CGAffineTransformMakeScale(0.3, 0.3);        imageView.transform = CGAffineTransformRotate(imageView.transform, M_PI);    } completion:^(BOOL finished) {        float x = IMAGE_WIDTH;        imageView.frame = CGRectMake(IMAGE_X, -30, x, x);        [_imagesArray addObject:imageView];    }];}

3.有代码有真相

#define IMAGE_X                arc4random()%(int)Main_Screen_Width#define IMAGE_ALPHA            ((float)(arc4random()%10))/10#define IMAGE_WIDTH            arc4random()%20 + 10#define PLUS_HEIGHT            Main_Screen_Height/25#define Main_Screen_Height      [[UIScreen mainScreen] bounds].size.height#define Main_Screen_Width       [[UIScreen mainScreen] bounds].size.width#import "ViewController.h"@interface ViewController ()@property (nonatomic ,strong) NSMutableArray *imagesArray;@property (nonatomic , strong) UIImageView *imageView;@end@implementation ViewController- (void)loadView{    UIImageView *imageView = [[UIImageView alloc]initWithFrame:[UIScreen mainScreen].bounds];    imageView.image = [UIImage imageNamed:@"backgound.jpg"];    imageView.contentMode  = UIViewContentModeScaleAspectFill;    self.view = imageView;}- (void)viewDidLoad{    [super viewDidLoad];    _imagesArray = [[NSMutableArray alloc] init];    for (int i = 0; i < 1000; ++ i) {        UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"snow"]];        float x = IMAGE_WIDTH;        imageView.frame = CGRectMake(IMAGE_X, -30, x, x);        imageView.alpha = IMAGE_ALPHA;        [self.view addSubview:imageView];        [_imagesArray addObject:imageView];    }    //创建时钟,并且添加到主循环中    CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(makeSnow)];    [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];}- (void)makeSnow{    if (_imagesArray.count > 0) {        UIImageView *imageView = _imagesArray[0];        [_imagesArray removeObjectAtIndex:0];        [self snowFall:imageView];    }}- (void)snowFall:(UIImageView *)imageView{    [UIView animateWithDuration:10 animations:^{        imageView.frame = CGRectMake(imageView.frame.origin.x, Main_Screen_Height, imageView.frame.size.width, imageView.frame.size.height);        imageView.transform = CGAffineTransformMakeScale(0.3, 0.3);        imageView.transform = CGAffineTransformRotate(imageView.transform, M_PI);    } completion:^(BOOL finished) {        float x = IMAGE_WIDTH;        imageView.frame = CGRectMake(IMAGE_X, -30, x, x);        [_imagesArray addObject:imageView];    }];}

4.Demo也不能少

https://github.com/Esdeath/snow/tree/master/SnowFlyTwo

1 0