在特定点停止CABasicAnimation

问题描述 投票:6回答:2

我正在使用由CABasicAnimation创建的旋转动画。它将UIView旋转2秒钟。但是我需要能够在触摸UIView时将其停止。如果删除动画,则视图与动画开始之前的位置相同。

这是我的动画代码:

float duration = 2.0;
float rotationAngle = rotationDirection * ang * speed * duration;
//rotationAngle =  3*(2*M_PI);//(double)rotationAngle % (double)(2*M_PI) ;
CABasicAnimation* rotationAnimation;
rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
rotationAnimation.toValue = [NSNumber numberWithFloat: rotationAngle ];
rotationAnimation.duration = duration;
rotationAnimation.cumulative = YES;
rotationAnimation.removedOnCompletion = NO;
rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
rotationAnimation.fillMode = kCAFillModeForwards;
rotationAnimation.delegate = self;

[self.view.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"];

当触摸UIView时,如何立即停止其旋转?我知道如何管理触摸部分,但我不知道如何以动画的当前角度停止视图。

解决方案:我通过获取表示层的角度,删除动画并设置视图的变换来解决该问题。这是代码:

[self.view.layer removeAllAnimations];      
CALayer* presentLayer = self.view.layer.presentationLayer; 
float currentAngle = [(NSNumber *)[presentLayer valueForKeyPath:@"transform.rotation.z"] floatValue];
self.view.transform = CGAffineTransformMakeRotation(currentAngle);
iphone objective-c ios ipad core-animation
2个回答
17
投票

好问题!为此,了解核心动画架构会很有帮助。

如果查看Core Animation Programming Guide中描述核心动画渲染体系结构的图,则可以看到有三棵树。

您有model树。那就是您设置want发生的值的地方。然后是presentation树。就运行时而言,这就是正在发生的事情。然后,最后是render树。这就是用户所看到的。

在您的情况下,您要查询表示树的值。

很容易做到。对于已附加动画的视图,获取layer,对于该layer,查询presentationLayer的值。例如:

CATransform3D myTransform = [(CALayer*)[self.view.layer presentationLayer] transform];

没有办法“暂停”动画中间流程。您所能做的就是查询值,将其删除,然后从上次中断的位置重新创建。

有点痛苦!

[例如,我在其他一些帖子中对此有更详细的介绍

Restoring animation where it left off when app resumes from background

也请记住,当您将动画添加到视图的图层时,实际上并没有更改基础视图的属性。那么会发生什么呢?我们会在动画停止的地方得到怪异的效果,并且您会在原始位置看到视图。

这是您需要使用CAAnimation委托的位置。看看我对这篇文章的回答,我将在这里进行介绍:

CABasicAnimation rotate returns to original position


5
投票

您需要将旋转设置为presentationLayer的旋转,然后从图层中删除动画。您可以在我的[Hit testing animating layers]博客文章中阅读有关表示层的信息。

用于设置最终旋转的代码将类似于:

self.view.layer.transform = [(CALayer*)[self.view.layer presentationLayer] transform];
[self.view.layer removeAnimationForKey:@"rotationAnimation"];
© www.soinside.com 2019 - 2024. All rights reserved.