在特定点停止 CABasicAnimation
Posted
技术标签:
【中文标题】在特定点停止 CABasicAnimation【英文标题】:Stop CABasicAnimation at specific point 【发布时间】:2012-06-19 10:07:07 【问题描述】:我正在使用CABasicAnimation
创建的旋转动画。它会在 2 秒内旋转 UIView
。但是当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);
【问题讨论】:
你把上面的解决方案放在哪里了??我总是得到角度 0.0000 【参考方案1】:好问题!为此,了解 Core Animation 架构会很有帮助。
如果您查看 Core Animation Programming Guide 中描述核心动画渲染架构的图表,您可以看到有三棵树。
你有 model 树。这就是您设置希望发生的值的地方。然后是 presentation 树。就运行时而言,这几乎就是发生的事情。然后,最后是 render 树。这就是用户所看到的。
在您的情况下,您想查询 presentation 树的值。
这很容易做到。对于附加动画的视图,获取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
【讨论】:
感谢表现层的讲解。我通过 valueForKeyPath: 获取presentationLayer的旋转角度解决了这个问题,设置了视图的变换并移除了动画。【参考方案2】:您需要将旋转设置为presentationLayer 的旋转,然后从图层中移除动画。您可以在我关于 Hit testing animating layers 的博文中了解表示层。
设置最终旋转的代码类似于:
self.view.layer.transform = [(CALayer*)[self.view.layer presentationLayer] transform];
[self.view.layer removeAnimationForKey:@"rotationAnimation"];
【讨论】:
以上是关于在特定点停止 CABasicAnimation的主要内容,如果未能解决你的问题,请参考以下文章