setAnimationRepeatAutoreverses not behaved as I expected

我与影子孤独终老i 提交于 2019-12-05 08:44:16

I've had exactly the same issue with using UIView animations on the alpha property. The worst part is that the animation jumps to the "final" position before the animationDidStop: delegate message is sent, which means you can't manually set the original state there.

My solution was to use the animationDidStop delegate messages to create a new animation block, and string them all together:

- (void)performAnimation
{
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(phase1AnimationDidStop:finished:context:)];

    // Do phase 1 of your animations here
    CGPoint center = someView.center;
    center.x += 100.0;
    center.y += 100.0;
    someView.center = center;

    [UIView commitAnimations];
}

- (void)phase1AnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
{
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(phase2AnimationDidStop:finished:context:)];

    // Do phase 2 of your animations here
    CGPoint center = someView.center;
    center.x -= 100.0;
    center.y -= 100.0;
    someView.center = center;

    [UIView commitAnimations];
}

- (void)phase2AnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
{
    // Perform cleanup (if necessary)
}

You can string together as many animation blocks as you want this way. It seems wasteful code-wise, but until Apple give us a -[UIView setAnimationFinishesInOriginalState:] property or something similar, this the only way that I've found to solve this problem.

I find out using an even number for setAnimationDuration will end repeat animation to its initial position and then pop to the final position after repeat animation ends. If I set setAnimationDuration to half cycle then the repeat animation will end to the final position. This is a cleaner way to handle animation than using setAnimationDidStopSelector: method.

// Repeat Swimming
CGPoint position = swimmingFish.center;
position.y = position.y - 100.0f;
position.x = position.x - 100.0f;

[UIView beginAnimations:nil context:nil]; 
[UIView setAnimationDuration:1.0f];
[UIView setAnimationRepeatCount:2.5];
[UIView setAnimationRepeatAutoreverses:YES];

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