取消一个UIViewanimation?

是否有可能在进行中取消UIViewanimation? 或者我将不得不下降到CA级别?

即我做了这样的事情(也许设置结束animation行动):

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

但在animation完成之前,我得到animation结束事件,我想取消它(缩短)。 这可能吗? 用谷歌search发现有几个人问同样的问题没有答案 – 一两个人猜测这是不能做的。

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

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

使用:

 #import <QuartzCore/QuartzCore.h> ....... [myView.layer removeAllAnimations]; 

最简单的方法就是立即停止某个特定视图上的所有animation:

将项目链接到QuartzCore.framework。 在你的代码的开始:

 #import <QuartzCore/QuartzCore.h> 

现在,当你想停止视图上的所有animation时,请说:

 [CATransaction begin]; [theView.layer removeAllAnimations]; [CATransaction commit]; 

中线会自行工作,但是直到runloop结束(“重绘时刻”)才会有延迟。 为了防止延迟,将命令封装在显式的事务处理块中,如图所示。 这个工作提供了没有其他的变化已经在这个层在当前的runloop执行。

在iOS 4及更高版本上, 使用第二个animationUIViewAnimationOptionBeginFromCurrentState选项将第一个animation缩短。

作为一个例子,假设你有一个活动指标的视图。 您希望淡化活动指标,同时开展一些耗时的活动,并在活动结束时将其淡出。 在下面的代码中,活动指示器的视图称为activityView

 - (void)showActivityIndicator { activityView.alpha = 0.0; activityView.hidden = NO; [UIView animateWithDuration:0.5 animations:^(void) { activityView.alpha = 1.0; }]; - (void)hideActivityIndicator { [UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^(void) { activityView.alpha = 0.0; } completion:^(BOOL completed) { if (completed) { activityView.hidden = YES; } }]; } 

要取消animation,只需要在UIViewanimation之外设置当前正在animation的属性。 这将停止animation,UIView将跳转到您刚刚定义的设置。

如果您通过更改常量而不是视图属性来激活约束,则其他方法都不会在iOS 8上运行。

示例animation:

 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) { }]; 

解:

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

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

如果你只是想暂停/停止animation顺利

 self.yourView.layer.speed = 0; 

来源: 如何暂停图层树的animation

以上都没有解决它对我来说,但这有助于: UIViewanimation立即设置属性,然后animation。 它在表示层匹配模型(set属性)时停止animation。

我解决了我的问题,那就是“我想从你看起来像你出现的地方开始animation”(“你”的意思)。 如果你想要的话,那么:

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

将该位置设置为表示层

我使用了几个选项,包括UIViewAnimationOptionOverrideInheritedDuration

但是,由于苹果的文档是模糊的,我不知道是否真的覆盖了其他animation使用,或者只是重置定时器。

 [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) {}]; 

这应该是一个体面的解决scheme。

 [UIView setAnimationsEnabled:NO]; // your code here [UIView setAnimationsEnabled:YES]; 

我有同样的问题; 这些API没有任何东西可以取消某些特定的animation。 该

+ (void)setAnimationsEnabled:(BOOL)enabled

禁用所有的animation,因此不适合我。 有两个解决scheme:

1)让你的animation对象成为子视图。 然后,当您要取消该视图的animation时,请移除视图或将其隐藏。 非常简单,但是如果需要保持在视图中,则需要重新创build没有animation的子视图。

2)重复animation只有一个,并作出一个委托select器重新启动animation,如果需要,如下所示:

 -(void) startAnimation { NSLog(@"startAnim alpha:%f", self.alpha); [self setAlpha:1.0]; [UIView beginAnimations:nil context:nil]; [UIView setAnimationDuration:1.0]; [UIView setAnimationRepeatCount:1]; [UIView setAnimationRepeatAutoreverses:YES]; [UIView setAnimationDelegate:self]; [UIView setAnimationDidStopSelector:@selector(pulseAnimationDidStop:finished:context:)]; [self setAlpha:0.1]; [UIView commitAnimations]; } - (void)pulseAnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context { if(hasFocus) { [self startAnimation]; } else { self.alpha = 1.0; } } -(void) setHasFocus:(BOOL)_hasFocus { hasFocus = _hasFocus; if(hasFocus) { [self startAnimation]; } } 

2)的问题是,在完成当前animation循环时总会有延迟停止animation。

希望这可以帮助。

即使您以上述方式取消animationdidStopSelector仍然运行。 所以,如果你的应用程序在由animation驱动的逻辑状态,你将有问题。 由于这个原因,我使用上面描述的方法使用UIViewanimation的上下文variables。 如果您通过上下文参数将当前的程序状态传递给animation,那么当animation停止时, didStopSelector函数可以决定是否应该执行某些操作,或者仅基于当前状态和作为上下文传递的状态值来返回。

 CALayer * pLayer = self.layer.presentationLayer; [UIView setAnimationBeginsFromCurrentState:YES]; [UIView animateWithDuration:0.001 animations:^{ self.frame = pLayer.frame; }]; 

要暂停animation而不将状态恢复为原始或最终:

 CFTimeInterval paused_time = [myView.layer convertTime:CACurrentMediaTime() fromLayer:nil]; myView.layer.speed = 0.0; myView.layer.timeOffset = paused_time; 

对不起复活这个答案,但在iOS 10的东西有点改变,现在取消是可能的,你甚至可以取消优雅!

在iOS 10之后,您可以使用UIViewPropertyAnimator取消animation!

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

如果通过,则取消animation,并在取消animation的位置停止。 完成方法不会被调用。 但是,如果您通过false,您将负责完成animation:

 animator.finishAnimation(.start) 

你可以完成你的animation并保持当前状态(.current)或者进入初始状态(.start)或者结束状态(.end)

顺便说一句,你甚至可以暂停,然后重新启动…

 animator.pauseAnimation() animator.startAnimation() 

注意:如果你不想突然取消,你可以改变你的animation,甚至在暂停之后改变你的animation!