I'm simulating some effects, like leafs falling, snow and rain. My first call was to use CAEmitterLayer, that works very well, but i need to render the layer in context to save as an image, and that seens impossible or, at least, very complicated.

So i am working with some view animations. I need to continuously animate my imageViews so it can fall through screen and reappear on top of it, each one with diffenrent speed.

So i relocate each imageView on screen with animateWithDuration and when animation is done i call the method that do that recursively from completion block so the imageview can make it's way to the end of screen. Once an imageView reachs the end of screen i relocate it on top.

The problem is when animation is over my imageView stops a little bit until the completion block calls the method recursively, i want it to be continuously.

My code generates random position for each imageView, and my animation duration is very short so i can always update imageView's location in case the user tap the button to save the view as an image.

Anyway, here is my code:

- (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];   
    }    
}

How can i make this animation repeatedly and continuously, without the gap when the method is called recursively from completion block and the animation restarts?

有帮助吗?

解决方案

You don't need to do the animation with 0 duration when the object reaches the end of the screen. Just test for this in your completion block and relocate the view before calling recursively. Also, a duration of 0.01 seems a bit extreme (100 frames per second). Perhaps a more reasonable value like 0.1 would help.

Something like this:

- (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];
                     }];
}

其他提示

From what I read briefly you should check out CAReplicatorLayer. It is perfect for repeating stuff! Only issue I can think of is that the transform and values have to be incremental...

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top