Multiple UIView Animations

让人想犯罪 __ 提交于 2019-12-12 09:27:01

问题


I am trying to perform multiple UIView animations one after the other. However, I've heard that it's bad practice to perform multiple UIView animations one after the other, and that I should instead use Core Animation. I tried this code:

//First Animation
[UIView beginAnimations:@"animation1" context:nil];
[UIView setAnimationDuration:2];
nwView.backgroundColor = [UIColor redColor];
nwView.frame = CGRectMake(CGRectGetMidX(screenSize),
                          CGRectGetMinY(screenSize),
                          width, 
                          height);
nwView.transform = CGAffineTransformMakeRotation(45.0f);
[UIView commitAnimations];

//Second Animation
[UIView beginAnimations:@"second animation" context:nil];
[UIView setAnimationDuration:2];

nwView.transform = CGAffineTransformMakeScale(0.5, 0.33);
nwView.backgroundColor = [UIColor purpleColor];

[UIView commitAnimations];

But it only does the second animation. I know this question is similar to UIView two animations coexisting, but it has a slightly different context.


回答1:


I don't think there is anything wrong with doing 2 animations in a row using UIView blocks. Just make sure you start your second animation in the completino block of the first animation.

Without blocks (your example) it is not working as you will have to set a delegate to the animation or set a selector for setAnimationDidStopSelector. There you should start the second animation.

But again, nothing wrong in doing animations with blocks (it is the preferred way).




回答2:


If you are looking to do multiple animations right after another this is not the way to do it. The code you posted with execute at almost the same time, meaning the animations would be performed at about the same time.

Instead what you should do is set the delegate for the first animation, and then do the first animation. Then when the animationDidStop method is called for the first animation, you should do the second animation. This makes sure they are one after another.

This is how you would do it, assuming you call doMyAnimations to start the animation.

-(void)doMyAnimations{
    //First Animation
    [UIView beginAnimations:@"animation1" context:nil];
    [UIView setAnimationDuration:2];
    [UIView setAnimationDelegate:self];
    nwView.backgroundColor = [UIColor redColor];
    nwView.frame = CGRectMake(CGRectGetMidX(screenSize),
                              CGRectGetMinY(screenSize),
                              width, 
                              height);
    nwView.transform = CGAffineTransformMakeRotation(45.0f);
    [UIView commitAnimations];
}

- (void)animationWillStart:(NSString *)animationID context:(void *)context{
}

- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context{
    if([animationID isEqualToString:@"animation1"]){
        //Second Animation
        [UIView beginAnimations:@"second animation" context:nil];
        [UIView setAnimationDuration:2];

        nwView.transform = CGAffineTransformMakeScale(0.5, 0.33);
        nwView.backgroundColor = [UIColor purpleColor];

        [UIView commitAnimations];
    }
}

Keep in mind that the nwView would have to be accessible throughout the entire class. If it isn't you can either make it an instance variable, or find another way to get access to it in the animationDidStop method.




回答3:


You can use blocks for this purpose and get a very clean result.

NSMutableArray* animationBlocks = [NSMutableArray new];

typedef void(^animationBlock)(BOOL);

// getNextAnimation
// removes the first block in the queue and returns it
animationBlock (^getNextAnimation)() = ^{
    animationBlock block = (animationBlock)[animationBlocks firstObject];
    if (block){
        [animationBlocks removeObjectAtIndex:0];
        return block;
    }else{
         return ^(BOOL finished){};
    }
};

//add a block to our queue
[animationBlocks addObject:^(BOOL finished){;
    [UIView animateWithDuration:1.0 animations:^{
        //...animation code...
    } completion: getNextAnimation()];
}];

//add a block to our queue
[animationBlocks addObject:^(BOOL finished){;
    [UIView animateWithDuration:1.0 animations:^{
        //...animation code...
    } completion: getNextAnimation()];
}];

//add a block to our queue
[animationBlocks addObject:^(BOOL finished){;
    NSLog(@"Multi-step Animation Complete!");
}];

// execute the first block in the queue
getNextAnimation()(YES);

Taken from: http://xibxor.com/objective-c/uiview-animation-without-nested-hell/



来源:https://stackoverflow.com/questions/10792026/multiple-uiview-animations

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!