19

我正在设置以下UIView animateWithDuration:方法,目的是在程序中的其他位置设置我的animationOn BOOL以取消该无限循环重复。我的印象是,每当动画的一个循环结束时,completion块就会被调用,但看起来并不是这样。使用BOOL /完成块停止自动反向/无限重复UIView动画

completion块是否在重复动画中调用过?如果不是,还有另外一种方法可以阻止这种方法之外的动画吗?

- (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]; 
         } 
    }]; 
} 

回答

45

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

停止动画,你可以从视图的层将其删除:

[button.layer removeAllAnimations]; 
+0

这没有用,恐怕。应用变换后的动画仍然在进行。 (我将'.transform'设置为'CGAffineTransformMakeScale(1.0,1.0)')。 – Luke

+0

我发现了其他可能工作的东西。我更新了我的答案。你可以试试吗? –

+0

哦,你自己想出来:)谢谢你接受我的答案无论如何 –

2

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

+0

我厌倦了这一点,但它对我不起作用。你从哪里调用这个方法? – Supertecnoboff

8

旧的,但另一种选择。

您还可以设置另一个不在同一视图上重复的动画,这样您也可以在当前状态下捕获它,并使用选项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){ 

        }]; 
} 
+0

这是比其他解决方案更好的方法,因为它可以顺利地将动画带回身份。 – Nikolozi

1

作为每个视类引用的文档:如果使用任何类的方法,如果诸如animateWithDuration:delay:options:animations:completion: 的持续时间被设定为负的值或0时,变化而不执行动画制作。 所以我做了这样的事情,停止无限循环动画:

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

我觉得这是不是删除从该层所有动画作为建议的回答更好。 请注意,这适用于UIView类中的所有其他类动画方法。

+0

这不适合我。我不得不调用removeAllAnimations。 –