ios 取消 UIView 动画?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/554997/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Cancel a UIView animation?
提问by philsquared
Is it possible to cancel a UIView
animation while it is in progress? Or would I have to drop to the CA level?
是否可以在UIView
动画进行中取消动画?还是我必须降到 CA 级别?
i.e. I've done something like this (maybe setting an end animation action too):
即我做过这样的事情(也许也设置了结束动画动作):
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:duration];
[UIView setAnimationCurve: UIViewAnimationCurveLinear];
// other animation properties
// set view properties
[UIView commitAnimations];
But before the animation completes and I get the animation ended event, I want to cancel it (cut it short). Is this possible? Googling around finds a few people asking the same question with no answers - and one or two people speculating that it can't be done.
但是在动画完成并获得动画结束事件之前,我想取消它(缩短它)。这可能吗?谷歌搜索发现有几个人在问同样的问题却没有答案——还有一两个人推测这是不可能的。
采纳答案by Stephen Darlington
The way I do it is to create a new animation to your end point. Set a very short duration and make sure you use the +setAnimationBeginsFromCurrentState:
method to start from the current state. When you set it to YES, the current animation is cut short. Looks something like this:
我这样做的方法是为您的终点创建一个新动画。设置一个非常短的持续时间并确保您使用该+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];
回答by Jim Heising
Use:
用:
#import <QuartzCore/QuartzCore.h>
.......
[myView.layer removeAllAnimations];
回答by matt
Simplest way to stop allanimations on a particular view, immediately, is this:
最简单的方法停止所有对特定视图的动画,立即,是这样的:
Link the project to QuartzCore.framework. At the start of your code:
将项目链接到 QuartzCore.framework。在代码的开头:
#import <QuartzCore/QuartzCore.h>
Now, when you want to stop all animations on a view dead in their tracks, say this:
现在,当你想停止一个视图上的所有动画时,请说:
[CATransaction begin];
[theView.layer removeAllAnimations];
[CATransaction commit];
The middle line would work all by itself, but there's a delay until the runloop finishes (the "redraw moment"). To prevent that delay, wrap the command in an explicit transaction block as shown. This works provided no other changes have been performed on this layer in the current runloop.
中间线会自己工作,但是在 runloop 完成之前会有一个延迟(“重绘时刻”)。为防止这种延迟,请将命令包装在显式事务块中,如图所示。如果在当前运行循环中没有对这一层执行其他更改,则此方法有效。
回答by Ville Laurikari
On iOS 4 and greater, use the UIViewAnimationOptionBeginFromCurrentState
optionon the second animation to cut the first animation short.
在 iOS 4 及更高版本上,使用UIViewAnimationOptionBeginFromCurrentState
第二个动画上的选项来缩短第一个动画。
As an example, assume you have a view with an activity indicator. You wish to fade in the activity indicator while some potentially time consuming activity begins, and fade it out when the activity is finished. In the code below, the view with the activity indicator on it is called activityView
.
例如,假设您有一个带有活动指示器的视图。您希望在一些可能耗时的活动开始时淡入活动指示器,并在活动结束时淡出它。在下面的代码中,带有活动指示器的视图被称为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;
}
}];
}
回答by tomtaylor
To cancel an animation you simply need to set the property that is currently being animated, outside of the UIView animation. That will stop the animation wherever it is, and the UIView will jump to the setting you just defined.
要取消动画,您只需在 UIView 动画之外设置当前正在设置动画的属性。这将在任何地方停止动画,并且 UIView 将跳转到您刚刚定义的设置。
回答by Tiago Almeida
Sorry to resurrect this answer, but in iOS 10 things kinda changed, and now cancelling is possible and you can even cancel gracefully!
很抱歉恢复这个答案,但在 iOS 10 中,事情发生了一些变化,现在可以取消,您甚至可以优雅地取消!
After iOS 10 you can cancel animations with UIViewPropertyAnimator!
在 iOS 10 之后,您可以使用UIViewPropertyAnimator取消动画!
UIViewPropertyAnimator(duration: 2, dampingRatio: 0.4, animations: {
view.backgroundColor = .blue
})
animator.stopAnimation(true)
If you pass true it cancels the animation and it stops right where you cancelled it. The completion method will not be called. However, if you pass false you are responsible for finishing the animation:
如果您传递 true 它会取消动画并在您取消它的地方停止。不会调用完成方法。但是,如果您传递 false,则您负责完成动画:
animator.finishAnimation(.start)
You can finish your animation and stay in the current state (.current) or go to the initial state (.start) or to the end state (.end)
您可以完成动画并保持当前状态 (.current) 或转到初始状态 (.start) 或结束状态 (.end)
By the way, you can even pause and restart later...
顺便说一句,您甚至可以稍后暂停并重新启动......
animator.pauseAnimation()
animator.startAnimation()
Note: If you don't want an abrupt cancelling you can reverse your animation or even change your animation after you pause it!
注意:如果您不想突然取消,您可以在暂停后反转动画甚至更改动画!
回答by Nikola Lajic
If you are animating a constraint by changing the constant instead of a view property none of the other methods work on iOS 8.
如果您通过更改常量而不是视图属性来为约束设置动画,则其他方法都不适用于 iOS 8。
Example 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) {
}];
Solution:
解决方案:
You need to remove the animations from the layers of any views being affected by the constraint change and their sublayers.
您需要从受约束更改及其子图层影响的任何视图的图层中删除动画。
[self.constraintView.layer removeAllAnimations];
for (CALayer *l in self.constraintView.layer.sublayers)
{
[l removeAllAnimations];
}
回答by Victor
If you just want to pause/stop animation smoothly
如果您只想平稳地暂停/停止动画
self.yourView.layer.speed = 0;
Source: How to pause the animation of a layer tree
来源:如何暂停图层树的动画
回答by ideawu
[UIView setAnimationsEnabled:NO];
// your code here
[UIView setAnimationsEnabled:YES];
回答by NazCodezz
None of the above solved it for me, but this helped: The UIView
animation sets the property immediately, then animates it. It stops the animation when the presentation layer matches the model (the set property).
以上都没有为我解决它,但这有帮助:UIView
动画立即设置属性,然后动画它。当表示层与模型(set 属性)匹配时,它会停止动画。
I solved my issue, which was "I want to animate from where you look like you appear" ('you' meaning the view). If you want THAT, then:
我解决了我的问题,即“我想从你看起来像的地方制作动画”(“你”的意思是视图)。如果你想要那个,那么:
- Add QuartzCore.
CALayer * pLayer = theView.layer.presentationLayer;
- 添加 QuartzCore。
CALayer * pLayer = theView.layer.presentationLayer;
set the position to the presentation layer
将位置设置为表示层
I use a few options including UIViewAnimationOptionOverrideInheritedDuration
我使用了一些选项,包括 UIViewAnimationOptionOverrideInheritedDuration
But because Apple's documentation is vague, I don't know if it really overrides the other animations when used, or just resets timers.
但是因为苹果的文档含糊不清,不知道是不是真的会在使用时覆盖其他动画,或者只是重置定时器。
[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) {}];
And that should be a decent solution for now.
现在这应该是一个不错的解决方案。