我想制作一个轮式菜单,允许用户旋转滚轮(UIImageView)以查看各种选项。在车轮的上半部分还有一个选择指示器,用户可以通过在车轮周围拖动所需选项并在选择指示器下方定位来选择特定选项(就像使用UIPickerView时一样)。
在SO iPhone - How to build a roulette like wheel?之后,我已经能够实现跟踪用户触摸的轮子并相应地旋转轮子。但是,我还需要两个额外的功能:
实现惯性滚动,以便用户可以在滚轮上滑动并旋转并优雅地减速/减速,有点像“财富之轮”游戏节目中的滚轮。
当车轮完成减速并完全停止时,它会自动停在其中一个选项上,因此选择指示器下方会出现一个选项(如UIPickerView),而不是可能有两个选项两者都在选择指标下面。
我不确定如何实施这些功能,因此非常感谢任何帮助。
答案 0 :(得分:2)
作为一个起点,您可能想要做的是跟踪用户滚动滚轮的程度。当用户开始触摸滚轮时,请使用
保存日期和当前角度NSDate *lastDate = [NSDate date];
double lastAngle = //however you're determining the wheel angle
然后在每个touchMoved上,使用当前时间和角度更新这些值。当你最终获得touchEnded时,获取自上次保存日期以来的时间间隔,并使用它来确定车轮的转速:
NSDate *currentDate = [NSDate date];
NSTimeInterval elapsedTime = [currentDate timeIntervalSinceDate];
double rotationalSpeed = (currentAngle - lastAngle) / elapsedTime;
现在你有一个角度/秒,轮子在用户的手指下旋转。目标是保持相同的速度,所以也许只需启动一个定时器,每秒启动一次,然后将轮子旋转到rotationSpeed * timeElapsedSinceLastTimerFired。通过保存调用计时器触发方法的实际日期来计算最后一个方法,类似于您跟踪上述轮角更新之间的时间。或者,角度更新之间可以有更长的间隔,并随着时间的推移设置旋转动画。当您的短动画完成时,您只需从另一个动画开始。
那些会让车轮无限期地以用户的最后速度转动。要逐渐减少它,你可能只需要一个可能每0.1秒触发一次的计时器,并减少rotationSpeed,直到它达到或低于零。更好的是,如何存储用户放开滚轮的日期,然后根据自用户停止交互以来的时间长度应用一部分的rotationSpeed。类似的东西:
CGFloat secondsUntilWheelShouldStop = 5;
NSTimeInterval intervalSinceUserStopped = [[NSDate date] timeIntervalSinceDate:userStoppedDate];
// Determine fraction of secondsUntilWheelShouldStop that's elapsed
CGFloat portionOfCooldownTimeElapsed = intervalSinceUserStopped / secondsUntilWheelShouldStop;
if (portionOfCooldownTimeElapsed >= 1.0) {
// Time has run out, so call your method to round to nearest "snap-to" angle or something and end.
[self snapWheelRotation];
} else {
// Rotate the wheel by the appropriate fraction of rotationalSpeed
double angleToRotate = (portionOfCooldownTimeElapsed * rotationalSpeed) * elapsedTimeSinceLastUpdate;
[self rotateWheelByAngle:angleToRotate];
}
停止滚轮时,只需确定最近的捕捉点是什么,并将滚轮设置为该位置的动画。你应该向touchesBegan添加一些内容,当用户触摸方向盘时,它基本上会结束所有这些定时器和动画,因此它不会在它们下方制作动画。
我不确定这是否是最优雅的解决方案,但如果我试图解决问题,那就是我要开始的地方。祝你好运!