Understanding of UIAnimation

2019-02-20 19:34发布

问题:

I am trying to use following code to perform few animations

-(void) performSlidingfromX:(int) xx fromY:(int) yy 
{
UIImageView *Image= [self getImage];

[UIView beginAnimations:nil context:NULL];  
[UIView setAnimationDuration: 1.0];
[UIView setAnimationBeginsFromCurrentState:true];
[UIView setAnimationCurve: UIViewAnimationCurveEaseOut];
[token setFrame:CGRectMake(xx, yy, 64, 64)];
[UIView commitAnimations];

}

and i am calling like it in for loop

for (i = 0; i < totMoves; i++) {
    Moment *m = [moments objectAtIndex:i];
    int xx= [m X];
    int yy= [m Y];

    [self performSlidingfromX:xx fromY:yy];

}

The problem that i am facing is that its animating to final position, for example , If i input the following moments for xx,yy

0,0
50,0
50,50

It moves the image from 0,0 to 50,50 diagonally, I want it to slide to horizantly first and then vertical.

Any Help?

Thanks

回答1:

use new block animations. it is easy and stable:

[UIView animateWithDuration:0.5 
                          delay:0 
                        options:UIViewAnimationOptionBeginFromCurrentState
                     animations:^{
                         [token setFrame:CGRectMake(xx, 0, 64, 64)];
                         //here you may add any othe actions, but notice, that ALL of them will do in SINGLE step. so, we setting ONLY xx coordinate to move it horizantly first.
                     } 
                     completion:^(BOOL finished){

                         //here any actions, thet must be done AFTER 1st animation is finished. If you whant to loop animations, call your function here.
                         [UIView animateWithDuration:0.5 
                                               delay:0 
                                             options:UIViewAnimationOptionBeginFromCurrentState 
                                          animations:^{[token setFrame:CGRectMake(xx, yy, 64, 64)];} // adding yy coordinate to move it verticaly} 
                                          completion:nil];
                     }];


回答2:

The problem is u continuously calling "performSlidingfromX:xx fromY:yy" inside for loop. Try this code:

     i=0;
     Moment *m = [moments objectAtIndex:i];
     int xx= [m X];
     int yy= [m Y];
     [self performSlidingfromX:xx fromY:yy];

-(void) performSlidingfromX:(int) xx fromY:(int) yy 
{
i++;
[UIView beginAnimations:nil context:NULL];  
[UIView setAnimationDuration: 1.0];
[UIView setAnimationBeginsFromCurrentState:true];
[UIView setAnimationCurve: UIViewAnimationCurveEaseOut];
[token setFrame:CGRectMake(xx, yy, 64, 64)];
[UIView commitAnimations];


[self performSelector:@selector(call:) withObject:[NSNumber numberWithInt:i] afterDelay:1.1];

}
-(void)call
{
 Moment *m = [moments objectAtIndex:i];
     int xx= [m X];
     int yy= [m Y];
     [self performSlidingfromX:xx fromY:yy];
 }


回答3:

Making an animation is not a blocking call. Your code does not stop and wait for the animation to finish. Immediately after you start the animation, the next iteration of your loop will run. That creates a new animation, which affects the same property, so it replaces the previous animation. The result you get is as if you had only run the last iteration of your loop.

Unfortunately there is no simple block of code to do what you want to do. You need to detect when the animation finishes, and then start the next one. You need to keep track of your state (mostly which i you are on) in something with wider scope than local variables.