gpt4 book ai didi

objective-c - 使用 CA 制作动画时圆形 slider 的怪异行为

转载 作者:搜寻专家 更新时间:2023-10-30 19:47:48 25 4
gpt4 key购买 nike

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

enter image description here

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

这是示例项目 -> 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"];

最佳答案

好的,我看了你的项目。您的问题是来回角度并不都落在 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。我在this answer做了很长的解释为什么这样做不好。

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

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

关于objective-c - 使用 CA 制作动画时圆形 slider 的怪异行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17694951/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com