如何使用GCD进行"连续"动画?

stu*_*yro 10 iphone core-animation grand-central-dispatch ios

我正在尝试UIView在远程通知到来时在屏幕上进行5秒的自定义显示.

像这样的代码:

//customView.alpha = 1.0 here
[UIView animateWithDuration:1 animations:^{
                                  customView.alpha = 0.3;
                              } 
                              completion:^(BOOL finished){
                                  // remove customView from super view.
                              }];
Run Code Online (Sandbox Code Playgroud)

问题和我需要的

但是有些情况可能会在很短的时间间隔内发出一些通知,其中有几个customView可能同时动画,而另一个可能会覆盖其他通知.

我希望这些动画一个接一个地执行,这样它们就不会发生冲突.

假设但失败了

//(dispatch_queue_t)queue was created in other parts of the code
dispatch_sync(queue, ^{
    [UIView animationWithDuration:animations:...];
});
Run Code Online (Sandbox Code Playgroud)

在GCD队列中制作动画后,我得到的结果与我使用的原始代码相同,后者没有使用GCD.动画仍然存在冲突.

顺便说一下,我听说涉及UI的动画或任务应该总是在主线程上运行,但在我的第二个代码中,动画看起来很平滑.为什么?

Dav*_*ist 4

如果每次运行的动画都是相同的,那么您可以只存储动画应该运行的次数(与动画的重复计数属性不同)。

当您收到远程通知时,您将增加计数器的值,并在计数器恰好为 1 时调用动画方法。然后在 methodThatAnimates 中,您在完成块中递归地调用自己,同时每次都会减少计数器。它看起来像这样(带有伪代码方法名称):

- (void)methodThatIsRunWhenTheNotificationIsReceived {
    // Do other stuff here I assume...
    self.numberOfTimesToRunAnimation = self.numberOfTimesToRunAnimation + 1;
    if ([self.numberOfTimesToRunAnimation == 1]) {
        [self methodThatAnimates];
    }
}

- (void)methodThatAnimates {
    if (self.numberOfTimesToRunAnimation > 0) {
        // Animation preparations ...
        [UIView animateWithDuration:1 
                         animations:^{
                                  customView.alpha = 0.3;
                         } 
                         completion:^(BOOL finished){
                                  // Animation clean up ...
                                  self.numberOfTimesToRunAnimation = self.numberOfTimesToRunAnimation - 1;
                                  [self methodThatAnimates];
                         }];
    }
}
Run Code Online (Sandbox Code Playgroud)