好吧所以我正在制作一些基本上可以用作旋钮的东西,但只有一半在屏幕上 - 所以我只需要水平滑动就可以使它旋转。我几乎所有的排序都有一个例外:如果你在中间滑动中改变滑动的方向,旋转不会改变方向。我甚至可以看到问题,但不知道如何处理解决方案。
所以在我的触摸动作中,我以可预测的方式滑动到弧度:
CGFloat radians = atan2f(location.y - centerY,location.x - centerX);
然后我存储弧度,将其加/减到先前的旋转,然后将结果提供给CATransform3D。
所以问题是,即使滑动改变方向,也存在“平衡”,不允许立即改变方向。
这有意义吗?
答案 0 :(得分:1)
首先,我希望你得到atan()返回-π/ 2 .. +π/ 2范围内的值,所以你永远不会得到圆圈另一半的值。 (如果你推断答案是在那一边,你必须自己翻转/镜像。)
在触摸移动的NSLog()中,您计算出新的差异,并确保它是您期望的值。
当然,你将之前的弧度保持在touchesBegan上,并在init,touchesEnded和touchesCancelled上保存当前的弧度,对吗?
(在很多情况下,touchesCancelled只能将参数转换为touchesEnded。)
如果你做了所有这些,那么你描述的方案应该有效。如果没有,可能会提供更多信息,例如当您认为这些值应该不同时,各种值的NSLog()输出。
答案 1 :(得分:1)
对于这样的交互,我发现通常效果最好的是在交互开始时保存状态和触地位置。然后,每当您更新时,根据原始触摸和当前触摸之间的距离计算新状态(作为与原始状态的差异应用)。
例如,在你提到的情况下,我在触摸时会做的是存储旋钮的当前角度和触摸的位置。然后,在触摸移动时,我将计算当前触摸位置和起始位置之间的差异。这将为您提供一个delta值,您可以将其转换为可以添加到起始角度的角度 - 相应地更新旋钮图形。这应该允许您在整个行为中改变方向,而不必担心跟上角度的增量变化。这也使得在一定角度之后处理诸如阻力或阻尼之类的东西变得非常容易 - 这比在逐步更新物体时处理它更容易。
答案 2 :(得分:1)
小心使用atan2来避免象限问题并将其除以零。这就是它的用途。
// angle with +ve x-axis, in the range [0, 2π)
float getDirection(CGPoint V)
{
double theta = atan2(V.x, V.y); // angle with +ve x-axis, in the range (−π, π]
if (theta < 0)
theta = 2 * M_PI - theta;
return theta;
}
+ (CGPoint) vectorFrom: (CGPoint) A to: (CGPoint) B
{ return CGPointMake(B.x - A.x, B.y - A.y); }
答案 3 :(得分:0)
我做了类似的事情来模拟转盘刮擦动作。尝试:
[CATransaction begin];
[CATransaction setValue:[NSNumber numberWithInt:0] forKey:kCATransactionAnimationDuration];
[myLayer setValue:[NSNumber numberWithFloat:radians] forKeyPath:@"transform.rotation.z"];
[CATransaction commit];
在视图的底层。