逐步顺利地停止UIImageView动画

JAH*_*lia 8 iphone objective-c uiimageview ios

我有以下简单的UIImageView动画:

-(void) setupTheAnimation {
  self.imgView.animationImages = imagesArr;
  [self.imgView setAnimationRepeatCount:-1];
  self.imgView.animationDuration =0.9;
  [self.imgView startAnimating];
  [self performSelector:@selector(stopTheAnimation) withObject:nil afterDelay:4.0];
}

-(void) stopTheAnimation {
  [self.imgView stopAnimating];
}
Run Code Online (Sandbox Code Playgroud)

但是当动画停止时我遇到了一个问题我不知道它停止的最后一帧是什么!所以动画的结尾根本不顺利.

所以我需要:

1)知道动画结束的最后一帧是什么,所以我将其设置为动画的最后一个图像,这导致平滑停止.

2)逐渐停止这个动画,即在停止之前改变其持续时间,然后先将其减速然后停止.

这是示例项目的链接.

Nat*_*ate 2

我知道您最初的实现使用,但我不知道直接使用连续可变持续时间的animationImages方法。然而,这是一个非常简单的功能,您可以自己实现。如果这样做,那么您可以在数组中的图像之间编写动态持续时间值。animationImages

在下面的代码中,我animationImages用自定义步进函数替换,并请求停止后动态调整持续时间。请注意,这与指定硬结束时间的原始代码略有不同。此代码指定齿轮旋转何时开始减慢。

如果您确实有一个硬动画周期,您可以调整调用stopTheAnimation以考虑您选择的减速因子(我只是在减速期间将每步的持续时间增加 10%,直到步数慢于给定阈值):

// my animation stops when the step duration reaches this value:
#define STOP_THRESHOLD_SECONDS 0.1f
#define NUM_IMAGES 35

@implementation ViewController
{
    NSMutableArray *imagesArr;
    int currentImage;
    BOOL stopRequested;
    NSTimeInterval duration;
}

-(void) setupTheAnimation {

    stopRequested = NO;
    currentImage = 0;
    duration = 0.9f / NUM_IMAGES;
    [self stepThroughImages];

    [self performSelector:@selector(stopTheAnimation) withObject:nil afterDelay:4.0];
}

- (void) stepThroughImages {

    self.imgView.image = [imagesArr objectAtIndex: currentImage];

    if (currentImage == NUM_IMAGES - 1) {
        currentImage = 0;
    } else {
        currentImage++;
    }

    if (stopRequested && duration < STOP_THRESHOLD_SECONDS) {
        // we're slowing down gradually
        duration *= 1.1f;
        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(duration * NSEC_PER_SEC));
        dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
            [self stepThroughImages];
        });
    } else if (!stopRequested) {
        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(duration * NSEC_PER_SEC));
        dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
            [self stepThroughImages];
        });
    }
}

-(void) stopTheAnimation {
    stopRequested = YES;
}
Run Code Online (Sandbox Code Playgroud)