是否有可能取消一个UIView动画,而它正在进行中?或者我必须降到CA级别?

例如,我做过这样的事情(可能设置了一个结束动画动作):

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:duration];
[UIView setAnimationCurve: UIViewAnimationCurveLinear];
// other animation properties

// set view properties

[UIView commitAnimations];

但是在动画完成之前,我得到动画结束事件,我想取消它(缩短它)。这可能吗?在谷歌上搜索一下,会发现一些人问了同样的问题,但没有答案——还有一两个人猜测这是不可能的。


当前回答

很抱歉要恢复这个答案,但在iOS 10中事情有点改变,现在取消是可能的,你甚至可以优雅地取消!

ios10之后,你可以用UIViewPropertyAnimator取消动画!

UIViewPropertyAnimator(duration: 2, dampingRatio: 0.4, animations: {
    view.backgroundColor = .blue
})
animator.stopAnimation(true)

如果你传递true,它会取消动画,并在你取消的地方停止。补全方法将不会被调用。然而,如果你传递了false,你将负责完成动画:

animator.finishAnimation(.start)

你可以完成动画并保持当前状态(.current)或回到初始状态(.start)或结束状态(.end)

顺便说一下,你甚至可以暂停并稍后重新启动……

animator.pauseAnimation()
animator.startAnimation()

注意:如果你不想突然取消,你可以反转你的动画,甚至在你暂停它后改变你的动画!

其他回答

如果你只是想平稳地暂停/停止动画

self.yourView.layer.speed = 0;

如何暂停一个层树的动画

如果你通过改变常量而不是视图属性来动画约束,其他方法在iOS 8上都不起作用。

示例动画:

self.constraint.constant = 0;
[self.view updateConstraintsIfNeeded];
[self.view layoutIfNeeded];
[UIView animateWithDuration:1.0f
                      delay:0.0f
                    options:UIViewAnimationOptionCurveLinear
                 animations:^{
                     self.constraint.constant = 1.0f;
                     [self.view layoutIfNeeded];
                 } completion:^(BOOL finished) {

                 }];

解决方案:

您需要从任何受约束更改影响的视图的层及其子层中删除动画。

[self.constraintView.layer removeAllAnimations];
for (CALayer *l in self.constraintView.layer.sublayers)
{
    [l removeAllAnimations];
}

以上这些方法都不能解决我的问题,但是这个方法有帮助:UIView动画会立即设置属性,然后将其动画化。当表示层与模型(set属性)匹配时,它会停止动画。

我解决了我的问题,那就是“我想从你出现的地方动画”(“你”指的是视图)。如果你想要那样,那么:

添加QuartzCore。 CALayer * pLayer = theView.layer.presentationLayer;

将位置设置为表示层

我使用了一些选项,包括UIViewAnimationOptionOverrideInheritedDuration

但由于苹果的文档是模糊的,我不知道它是否真的覆盖其他动画时使用,或只是重置计时器。

[UIView animateWithDuration:blah... 
                    options: UIViewAnimationOptionBeginFromCurrentState ... 
                    animations: ^ {
                                   theView.center = CGPointMake( pLayer.position.x + YOUR_ANIMATION_OFFSET, pLayer.position.y + ANOTHER_ANIMATION_OFFSET);
                   //this only works for translating, but you get the idea if you wanna flip and scale it. 
                   } completion: ^(BOOL complete) {}];

现在这应该是一个不错的解决方案。

Use:

#import <QuartzCore/QuartzCore.h>

.......

[myView.layer removeAllAnimations];

我的方法是创建一个新的动画到你的终点。设置一个非常短的持续时间,并确保使用+setAnimationBeginsFromCurrentState:方法从当前状态开始。当您将其设置为YES时,当前动画将被缩短。看起来是这样的:

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.1];
[UIView setAnimationCurve: UIViewAnimationCurveLinear];
// other animation properties

// set view properties

[UIView commitAnimations];