是否有可能取消一个UIView动画,而它正在进行中?或者我必须降到CA级别?
例如,我做过这样的事情(可能设置了一个结束动画动作):
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:duration];
[UIView setAnimationCurve: UIViewAnimationCurveLinear];
// other animation properties
// set view properties
[UIView commitAnimations];
但是在动画完成之前,我得到动画结束事件,我想取消它(缩短它)。这可能吗?在谷歌上搜索一下,会发现一些人问了同样的问题,但没有答案——还有一两个人猜测这是不可能的。
如果你通过改变常量而不是视图属性来动画约束,其他方法在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];
}
在一个特定的视图上立即停止所有动画的最简单的方法是:
将项目链接到QuartzCore.framework。在代码的开头:
#import <QuartzCore/QuartzCore.h>
现在,当你想停止视图中的所有动画时,这样说:
[CATransaction begin];
[theView.layer removeAllAnimations];
[CATransaction commit];
中线可以自己工作,但是在运行循环结束之前会有一个延迟(“重画时刻”)。为了防止这种延迟,可以将命令包装在显式事务块中,如图所示。如果在当前运行循环中没有对该层执行其他更改,则此工作正常。
以上这些方法都不能解决我的问题,但是这个方法有帮助: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) {}];
现在这应该是一个不错的解决方案。
在ios4及更高版本上,在第二个动画上使用UIViewAnimationOptionBeginFromCurrentState选项来缩短第一个动画。
例如,假设您有一个带有活动指示器的视图。您希望在一些潜在耗时的活动开始时淡出活动指示器,并在活动结束时淡出活动指示器。在下面的代码中,带有活动指示器的视图称为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;
}
}];
}