0

我正在模拟一些效果,例如落叶、下雪和下雨。我的第一个调用是使用 CAEmitterLayer,效果很好,但我需要在上下文中渲染图层以保存为图像,这看起来不可能,或者至少非常复杂。

所以我正在处理一些视图动画。我需要不断地为我的 imageViews 设置动画,以便它可以穿过屏幕并重新出现在它上面,每个都具有不同的速度。

所以我在屏幕上重新定位每个imageView animateWithDuration,当动画完成时,我调用从完成块递归执行该操作的方法,以便imageview可以到达屏幕末尾。一旦 imageView 到达屏幕末尾,我将其重新定位在顶部。

问题是当动画结束时,我的 imageView 会停止一点,直到完成块递归地调用该方法,我希望它是连续的。

我的代码为每个 imageView 生成随机位置,并且我的动画持续时间很短,所以我可以随时更新 imageView 的位置,以防用户点击按钮将视图保存为图像。

无论如何,这是我的代码:

- (void)effectOnObject:(UIImageView *)object{
    NSInteger initialX;
    NSInteger initialy;
    CGFloat duration;

    //the object have reached the end of screen
    if (object.frame.origin.y >= self.frame.size.height) {
        //generate random position to relocate the object on x axis
        initialX = arc4random() % 321;

        //generate random position to relocate the object on y axis (little bit above top of screen)
        initialy = ((NSInteger)-object.frame.size.height) - arc4random() % 11;

        //duration 0 so the object can be replaced without animation
        duration = 0.0;
    }
    else{
        initialX = object.frame.origin.x;

        //this change the speed of object
        initialy = object.frame.origin.y + 10

        //setted duration to short time
        duration = 0.01;
    }

    [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionAllowAnimatedContent 
     animations:^{
        [object setFrame:CGRectMake(initialX, initialy, object.frame.size.width, object.frame.size.height)];
     }
     completion:^(BOOL completed){
         //recursively call
         [self effectOnObject:object];                   
      }];
}

- (void)startEffect{

    //initiate effect on each imageView
    for (UIImageView *object in self.subviews) {
        [self effectOnObject:object];   
    }    
}

当从完成块递归调用该方法并且动画重新启动时,我怎样才能重复和连续地制作这个动画,而没有间隙?

4

2 回答 2

1

当对象到达屏幕末端时,您不需要执行 0 持续时间的动画。只需在完成块中对此进行测试并在递归调用之前重新定位视图。此外,0.01 的持续时间似乎有点极端(每秒 100 帧)。也许像 0.1 这样更合理的值会有所帮助。

像这样的东西:

- (void)effectOnObject:(UIImageView *)object{

    //setted duration to short time
    CGFloat duration = 0.1;

    [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionAllowAnimatedContent
                     animations:^{

                         NSInteger initialX = object.frame.origin.x;

                         //this change the speed of object
                         NSInteger initialy = object.frame.origin.y + 10;

                         [object setFrame:CGRectMake(initialX, initialy, object.frame.size.width, object.frame.size.height)];
                     }
                     completion:^(BOOL completed){

                         NSInteger initialX = arc4random() % 321;

                         //generate random position to relocate the object on y axis (little bit above top of screen)
                         NSInteger initialy = ((NSInteger)-object.frame.size.height) - arc4random() % 11;

                         [object setFrame:CGRectMake(initialX, initialy, object.frame.size.width, object.frame.size.height)];

                         //recursively call
                         [self effectOnObject:object];
                     }];
}
于 2013-11-12T14:36:35.093 回答
0

从我简要阅读的内容来看,您应该检查一下CAReplicatorLayer。它非常适合重复的东西!我能想到的唯一问题是转换和值必须是增量的......

于 2013-11-12T15:11:33.227 回答