4

我想制作一个可拖动和动画的圆形滑块。到目前为止,我已经设法构建了滑块并使用拖动手柄来移动它,甚至动画它。有时动画会出错(方向错误或最短方向。我将 UIView 子类化(很快将成为 UIControl,只是想先让动画正确)添加了 PanGestureRecognizer 和几个图层用于绘图。

在此处输入图像描述

那么如何解决这种奇怪的行为呢?我有人可以在这里帮助我,我将不胜感激:)

这是示例项目-> http://cl.ly/2l0O3b1I3U0X

非常感谢!

编辑:

这是绘图代码:

CALayer *aLayer = [CALayer layer];
aLayer.bounds = CGRectMake(0, 0, 170, 170);
aLayer.position = self.center;
aLayer.transform = CATransform3DMakeRotation(M_PI_4, 0, 0, 1);

self.handleHostLayer = [CALayer layer];
self.handleHostLayer.bounds = CGRectMake(0, 0, 170, 170);
self.handleHostLayer.position = CGPointMake(CGRectGetMaxX(aLayer.bounds) - 170/2.0, CGRectGetMaxY(aLayer.bounds) - 170/2.0);

[aLayer addSublayer:self.handleHostLayer];
[self.layer addSublayer:aLayer];

self.handle = [CALayer layer];
self.handle.bounds = CGRectMake(0, 0, 50, 50);
self.handle.cornerRadius = 25;
self.handle.backgroundColor = [UIColor whiteColor].CGColor;
self.handle.masksToBounds = NO;
self.handle.shadowOffset = CGSizeMake(3.0, 0.0);
self.handle.shadowRadius = 0;
self.handle.shadowOpacity = .15;
self.handle.shadowColor = [UIColor blackColor].CGColor;

[self.handleHostLayer addSublayer:self.self.handle];

这是动画代码:

CGFloat handleTarget = ToRad(DEG);

CABasicAnimation *rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
rotationAnimation.fromValue = @([[self.handleHostLayer valueForKeyPath:@"transform.rotation"] floatValue]);
rotationAnimation.toValue = @(handleTarget);
rotationAnimation.duration = .5;
rotationAnimation.removedOnCompletion = NO;
rotationAnimation.fillMode = kCAFillModeForwards;
rotationAnimation.cumulative = YES;
rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];

[self.handleHostLayer addAnimation:rotationAnimation forKey:@"transform.rotation"];
4

1 回答 1

1

好的,我看了你的项目。您的问题是 to 和 from 角度不都落在 0≤ɸ<2π 范围内。

您可以通过添加和删除 2π 来确保它们确实如此,直到它们都在该范围内。

CGFloat fromAngle = [[self.handleHostLayer valueForKeyPath:@"transform.rotation"] floatValue];
CGFloat toAngle   = handleTarget;

while (fromAngle >= 2.0*M_PI) { fromAngle -= 2*M_PI; }
while (toAngle   >= 2.0*M_PI) { toAngle   -= 2*M_PI; }
while (fromAngle <  0.0)      { fromAngle += 2*M_PI; }
while (toAngle   <  0.0)      { toAngle   += 2*M_PI; }

CABasicAnimation *rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
rotationAnimation.fromValue = @(fromAngle);
rotationAnimation.toValue   = @(toAngle);
// As before...

您可以改变的另一件事是滥用removeOnCompletion. 我在这个答案中做了很长的解释,说明为什么这样做不好。

简而言之:您不是根据您认为正在制作动画的值制作动画,因为您无意中引入了图层属性的值与您在屏幕上看到的值之间的差异。

一起跳过那条线。您也可以跳过跳过累积线,因为您不重复动画。现在,如果您的动画不粘:在添加动画之前将模型值设置为其最终值。

于 2013-07-17T12:49:37.067 回答