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

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

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

// set view properties

[UIView commitAnimations];

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


当前回答

Use:

#import <QuartzCore/QuartzCore.h>

.......

[myView.layer removeAllAnimations];

其他回答

斯蒂芬·达林顿解决方案的快速版本

UIView.beginAnimations(nil, context: nil)
UIView.setAnimationBeginsFromCurrentState(true)
UIView.setAnimationDuration(0.1)
// other animation properties

// set view properties
UIView.commitAnimations()

Even if you cancel the animation in the ways above animation didStopSelector still runs. So if you have logic states in your application driven by animations you will have problems. For this reason with the ways described above I use the context variable of UIView animations. If you pass the current state of your program by the context param to the animation, when the animation stops your didStopSelector function may decide if it should do something or just return based on the current state and the state value passed as context.

没有一个解决方案对我有效。我用这种方式解决了我的问题(我不知道这是否是正确的方式?),因为我在调用这个太快的时候有问题(当以前的动画还没有完成的时候)。我通过customAnim块传递我想要的动画。

extension UIView
{

    func niceCustomTranstion(
        duration: CGFloat = 0.3,
        options: UIView.AnimationOptions = .transitionCrossDissolve,
        customAnim: @escaping () -> Void
        )
    {
        UIView.transition(
            with: self,
            duration: TimeInterval(duration),
            options: options,
            animations: {
                customAnim()
        },
            completion: { (finished) in
                if !finished
                {
                    // NOTE: This fixes possible flickering ON FAST TAPPINGS
                    // NOTE: This fixes possible flickering ON FAST TAPPINGS
                    // NOTE: This fixes possible flickering ON FAST TAPPINGS
                    self.layer.removeAllAnimations()
                    customAnim()
                }
        })

    }

}

在一个特定的视图上立即停止所有动画的最简单的方法是:

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

#import <QuartzCore/QuartzCore.h>

现在,当你想停止视图中的所有动画时,这样说:

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

中线可以自己工作,但是在运行循环结束之前会有一个延迟(“重画时刻”)。为了防止这种延迟,可以将命令包装在显式事务块中,如图所示。如果在当前运行循环中没有对该层执行其他更改,则此工作正常。

我也有同样的问题;api没有任何东西来取消某些特定的动画。的

+ (void) setAnimationsEnabled:(BOOL)启用

禁用所有动画,因此不为我工作。有两种解决方案:

1)使你的动画对象成为子视图。然后,当你想要取消该视图的动画时,删除该视图或隐藏它。很简单,但是你需要重新创建没有动画的子视图如果你需要保持它在视图中。

2)只重复一个anim,并在需要时创建一个委托选择器重新启动anim,如下所示:

-(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)总是延迟停止动画,因为它完成当前的动画周期。

希望这能有所帮助。