使用BOOL /完成块停止自动反转/无限重复UIView动画

时间:2022-11-06 00:11:14

I'm setting up the following UIView animateWithDuration: method, with the intention of setting my animationOn BOOL elsewhere in the program to cancel that infinite looped repeat. I was under the impression that the completion block would be called each time a cycle of the animation ends, but this doesn't appear to be the case.

我正在设置以下UIView animateWithDuration:方法,目的是在程序中的其他位置设置我的animationOn BOOL以取消无限循环重复。我的印象是每次动画循环结束时都会调用完成块,但事实并非如此。

Is the completion block ever called in a repeating animation? And if not, is there another way I can stop this animation from outside this method?

是否在重复动画中调用了完成块?如果没有,是否有另一种方法可以在此方法之外停止此动画?

- (void) animateFirst: (UIButton *) button
{
    button.transform = CGAffineTransformMakeScale(1.1, 1.1);
    [UIView animateWithDuration: 0.4
                          delay: 0.0
                        options: UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat
                     animations: ^{
                         button.transform = CGAffineTransformIdentity;
                     } completion: ^(BOOL finished){
                         if (!animationOn) {
                             [UIView setAnimationRepeatCount: 0];
                         }
    }];
}

4 个解决方案

#1


48  

The completion block will only get called when the animation is interrupted. For example it gets called when the app goes in the background and comes back to the foreground again (via multitasking). In that case the animation is stopped. You should restart the animation when that happens.

只有在动画中断时才会调用完成块。例如,当应用程序进入后台并再次返回前台时(通过多任务处理),它会被调用。在这种情况下,动画停止。发生这种情况时应该重新启动动画。

To stop the animation you can remove it from the view's layer:

要停止动画,您可以从视图的图层中删除它:

[button.layer removeAllAnimations];

#2


8  

Old but another option.

旧但另一种选择。

You can also setup another animation which is not repeating on the same view, that way you can also capture it in the current state and return it to how it is by using the option UIViewAnimationOptionBeginFromCurrentState. Your completion block is also called.

您还可以设置另一个不在同一视图上重复的动画,这样您也可以在当前状态下捕获它并使用选项UIViewAnimationOptionBeginFromCurrentState将其返回到它的状态。您的完成块也会被调用。

-(void)someEventSoStop
{
    button.transform = CGAffineTransformMakeScale(1.0, 1.0);
    [UIView animateWithDuration: 0.4
                          delay: 0.0
                        options: UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionBeginFromCurrentState
                     animations: ^{
                         button.transform = CGAffineTransformIdentity;
                     } completion: ^(BOOL finished){

                     }];
}

#3


2  

I've solved the problem by calling [button.layer removeAllAnimations].

我通过调用[button.layer removeAllAnimations]解决了这个问题。

#4


1  

As per the documentation of View class reference: If you used any of the class methods such as animateWithDuration:delay:options:animations:completion: if the duration is set to negative value or 0, the changes are made without performing animation. so I did something like this to stop the infinite animation:

根据View类引用的文档:如果您使用了任何类方法,例如animateWithDuration:delay:options:animations:completion:如果持续时间设置为负值或0,则进行更改而不执行动画。所以我做了这样的事情来阻止无限动画:

[UIView animateWithDuration:0.0 animations:^{
      button.layer.affineTransform = CGAffineTransformIdentity;
  }];

I think this is better than removing all animations from the layer as in the suggested answer. Note that this is applicable for all other class animation methods in the UIView class.

我认为这比从建议的答案中删除图层中的所有动画要好。请注意,这适用于UIView类中的所有其他类动画方法。

#1


48  

The completion block will only get called when the animation is interrupted. For example it gets called when the app goes in the background and comes back to the foreground again (via multitasking). In that case the animation is stopped. You should restart the animation when that happens.

只有在动画中断时才会调用完成块。例如,当应用程序进入后台并再次返回前台时(通过多任务处理),它会被调用。在这种情况下,动画停止。发生这种情况时应该重新启动动画。

To stop the animation you can remove it from the view's layer:

要停止动画,您可以从视图的图层中删除它:

[button.layer removeAllAnimations];

#2


8  

Old but another option.

旧但另一种选择。

You can also setup another animation which is not repeating on the same view, that way you can also capture it in the current state and return it to how it is by using the option UIViewAnimationOptionBeginFromCurrentState. Your completion block is also called.

您还可以设置另一个不在同一视图上重复的动画,这样您也可以在当前状态下捕获它并使用选项UIViewAnimationOptionBeginFromCurrentState将其返回到它的状态。您的完成块也会被调用。

-(void)someEventSoStop
{
    button.transform = CGAffineTransformMakeScale(1.0, 1.0);
    [UIView animateWithDuration: 0.4
                          delay: 0.0
                        options: UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionBeginFromCurrentState
                     animations: ^{
                         button.transform = CGAffineTransformIdentity;
                     } completion: ^(BOOL finished){

                     }];
}

#3


2  

I've solved the problem by calling [button.layer removeAllAnimations].

我通过调用[button.layer removeAllAnimations]解决了这个问题。

#4


1  

As per the documentation of View class reference: If you used any of the class methods such as animateWithDuration:delay:options:animations:completion: if the duration is set to negative value or 0, the changes are made without performing animation. so I did something like this to stop the infinite animation:

根据View类引用的文档:如果您使用了任何类方法,例如animateWithDuration:delay:options:animations:completion:如果持续时间设置为负值或0,则进行更改而不执行动画。所以我做了这样的事情来阻止无限动画:

[UIView animateWithDuration:0.0 animations:^{
      button.layer.affineTransform = CGAffineTransformIdentity;
  }];

I think this is better than removing all animations from the layer as in the suggested answer. Note that this is applicable for all other class animation methods in the UIView class.

我认为这比从建议的答案中删除图层中的所有动画要好。请注意,这适用于UIView类中的所有其他类动画方法。