首页 > 代码库 > 定时器与 UIView 动画结合的雪花降落的效果

定时器与 UIView 动画结合的雪花降落的效果

 1 #import "HUAppDelegate.h" 2  3 @implementation HUAppDelegate 4  5 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 6 { 7     self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 8     self.window.backgroundColor = [UIColor whiteColor]; 9     [self.window makeKeyAndVisible];10     11     UIImageView *bg = [[UIImageView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];12     bg.image = [UIImage imageNamed:@"xueshan.jpg"];13     [self.window addSubview:bg];14     15     _snowArray = [[NSMutableArray alloc] init];16     UIImageView *snow = nil;17     for (int i  = 0; i < 50; i ++)18     {19         snow = [[UIImageView alloc] initWithFrame:CGRectMake(arc4random() % 320, -20, 20, 20)];20         snow.image = [UIImage imageNamed:@"flake.png"];21         snow.tag = 0;22         [self.window addSubview:snow];23         [_snowArray addObject:snow];24     }25     26     [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(findSnow) userInfo:nil repeats:YES];27     28     29     return YES;30 }31 32 //找雪花33 - (void)findSnow34 {35     UIImageView *aSnow = nil;36     for (int i = 0; i < _snowArray.count; i ++)37     {38         aSnow = [_snowArray objectAtIndex:i];39         if (aSnow.tag == 0)40         {41             aSnow.tag = 1;42 //            [self snowDown:aSnow];  //如果将这句代码放在这里,后面的 else 以及后面的代码都可以不要,因为放在这里不会出现不被允许动画的雪花又被调用执行一次动画43             break;44         }45         else46         {47             aSnow = nil;   //找雪花的时候没有一朵雪花是符合条件的,但这时候 aSnow 仍然有一个值,如果不让它指向空的时候,最后一朵雪花(第50朵)又被使用了一次,此时这多雪花下落的动画还没有结束,再次使用会造成意想不到的结果(有一朵雪花会往上飞)。这个 bug 折磨了我一天,最后还是老师帮助解决的,思维进入了一个误区,还真的是害人不浅。48         }49     }50 51     [self snowDown:aSnow];  //调用雪花动画的方法,即时让被找到的这朵雪花进行动画52 }53 54 //让一朵雪花动画55 - (void)snowDown:(UIImageView *)aSnow56 {57     [UIView beginAnimations:nil context:aSnow];58     [UIView setAnimationDuration:7];59     aSnow.frame = CGRectMake(arc4random() % 320 , 480, 20, 20);60     [UIView setAnimationDelegate:self];61     [UIView setAnimationDidStopSelector:@selector(restart:finished:context:)];62     [UIView commitAnimations];63 }64 65 - (void)restart:(NSString *)animationID finished:(NSNumber *)finished context:(void *)aSnow66 {67     UIImageView * snow = (UIImageView *)aSnow;68     snow.frame = CGRectMake(arc4random() % 320, -20, 20, 20);69     snow.tag = 0;70 }//让已经下落到底部的动画重新定位到顶部,达到重用的效果,并且重置 tag 值,此时这多雪花就可以被重新找到,再次进行下落的动画71 72 /*73  注意上面的定时器的时间间隔(0.14)以及雪花下落动画所需要的时间(7),以及数组的长度(50)74  0.14 * 50 = 775  这个时间去的有点巧妙,这是一个临界值,本来我是本着不浪费的原则让每一朵雪花都能够没找到然后进76  动画,然后出现了上面的 bug, 如果将时间间隔调小一点(雪花动画会出现断层,最后一朵雪花的动画77  果也会受到影响,此时将数组长度减至10,会发现只有 9 多雪花进行了动画,原理同上),如果将时间78  调大是可以解决问题的,因为此时在找到最后一朵雪花之前,已经有雪花重新在进行一轮动画了。79  */80 81 @end

这种使用定时器与 UIView 动画结合制作的动画效果既不僵硬,然后又能够对雪花对象重用,节省了内存,是比较好的方式。

到这里,动画的学习已经结束了一个阶段,在使用过程中需要结合实际情况选择。

定时器与 UIView 动画结合的雪花降落的效果