【问题标题】:What is the best way to stop a chain of block based animations停止基于块的动画链的最佳方法是什么
【发布时间】:2012-01-01 16:13:33
【问题描述】:

假设基于块的动画链如下:

UIView * view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];

//animation 1
[UIView animateWithDuration:2 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
     view.frame = CGRectMake(0, 100, 200, 200);
} completion:^(BOOL finished){

     //animation 2
     [UIView animateWithDuration:2 delay:0 options: UIViewAnimationOptionRepeat |UIViewAnimationOptionAutoreverse animations:^{
          [UIView setAnimationRepeatCount:1.5];
          view.frame = CGRectMake(50, 100, 200, 200);   
     } completion:^(BOOL finished){

          //animation 3
          [UIView animateWithDuration:2 delay:0 options:0 animations:^{
               view.frame = CGRectMake(50, 0, 200, 200);
          } completion:nil];
     }];
}];

停止这种动画的最佳方法是什么?只是打电话

[view.layer removeAllAnimations];

还不够,因为这只会停止当前正在执行的动画块,其余的将按顺序执行。

【问题讨论】:

  • 编译器允许吗?我在嵌套这么深的块时遇到了麻烦。 (现在不记得是 gcc 还是 clang 了——更可能的是,clang 允许更深入,但仍然不是很多。)
  • iOS 4 及更高版本支持基于块的动画。嵌套效果很好。
  • 那么要么编译器错误得到修复,你正在使用clang,要么你没有达到限制。

标签: iphone objective-c ios ipad ios4


【解决方案1】:

您可以查阅传入完成块的finished BOOL。如果您调用了removeAllAnimations,则为NO。

【讨论】:

  • 调用 removeAllAnimations 后完成的 BOOL 为 YES。
  • 它应该像你说的那样是 NO,但它是 YES...“这个块没有返回值,并采用一个布尔参数来指示动画是否在完成处理程序之前完成称为“
  • 在你所有的完成块中?如果动画没有完成,它应该是 NO。否则,我认为您的其他解决方案是正确的做法。
  • Jesse 你的建议在设置 UIViewAnimationOptionAllowUserInteraction 选项时有效。
  • 哇,这是一个非常随机的发现。我想知道为什么这很重要。
【解决方案2】:

我使用以下方法:

UIView * view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];

//set the animating flag
animating = YES;

//animation 1
[UIView animateWithDuration:2 delay:0 options:UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction animations:^{
     view.frame = CGRectMake(0, 100, 200, 200);
} completion:^(BOOL finished){
     //stops the chain
     if(! finished) return;

     //animation 2
     [UIView animateWithDuration:2 delay:0 options: UIViewAnimationOptionRepeat |UIViewAnimationOptionAutoreverse | UIViewAnimationOptionAllowUserInteraction  animations:^{
          [UIView setAnimationRepeatCount:1.5];
          view.frame = CGRectMake(50, 100, 200, 200);   
     } completion:^(BOOL finished){
          //stops the chain
          if(! finished) return;

          //animation 3
          [UIView animateWithDuration:2 delay:0 options:0 animations:^{
               view.frame = CGRectMake(50, 0, 200, 200);
          } completion:nil];
    }];
}];

- (void)stop {
     animating = NO;
     [view.layer removeAllAnimations];
}

removeAllAnimations 消息立即停止动画块并调用其完成块。在那里检查动画标志并停止链。

有没有更好的方法?

【讨论】:

  • 在某些情况下,您可能希望从所有视图中删除动画。 for(UIView * view in [self.view subviews]) { [view.layer removeAllAnimations]; }
  • 您没有在选项中设置UIViewAnimationOptionAllowUserInteraction。如何调用stop?用户水龙头/平底锅?如果是这样,则不会根据您的代码调用stop。看看...无论如何,应该使用finished,如上所述。
  • 你是对的,动画标志是不必要的,添加 UIViewAnimationOptionAllowUserInteraction 选项并替换 if(! animating) return;如果(!完成)返回;是这样做的方法。
  • 谢谢!节省了我几个小时!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-28
  • 2020-12-06
  • 1970-01-01
  • 1970-01-01
  • 2022-08-23
  • 1970-01-01
相关资源
最近更新 更多