轮子式iPhone菜单

轮子式iPhone菜单,iphone,objective-c,cocoa-touch,animation,core-animation,Iphone,Objective C,Cocoa Touch,Animation,Core Animation,我想制作一个轮子样式菜单,允许用户旋转轮子(UIImageView)以查看各种选项。在控制盘的上半部分还有一个选择指示器,用户可以通过在控制盘周围拖动所需选项并将其放置在选择指示器下方来选择特定选项(就像使用UIPickerView时一样) 根据SO post,我已经能够实现一个轮子,它跟踪用户的触摸并相应地旋转轮子。但是,我需要两个附加功能: 实现惯性滚动,这样用户可以在滚轮上滑动,滚轮旋转并优雅地减速,有点像“命运之轮”游戏中的滚轮 当车轮完成减速并完全停止时,它将在其中一个选项上自动停止,

我想制作一个轮子样式菜单,允许用户旋转轮子(UIImageView)以查看各种选项。在控制盘的上半部分还有一个选择指示器,用户可以通过在控制盘周围拖动所需选项并将其放置在选择指示器下方来选择特定选项(就像使用UIPickerView时一样)

根据SO post,我已经能够实现一个轮子,它跟踪用户的触摸并相应地旋转轮子。但是,我需要两个附加功能:

  • 实现惯性滚动,这样用户可以在滚轮上滑动,滚轮旋转并优雅地减速,有点像“命运之轮”游戏中的滚轮

  • 当车轮完成减速并完全停止时,它将在其中一个选项上自动停止,以便在选择指示器下方显示一个选项(如UIPickerView),而不是在选择指示器下方同时显示两个选项


  • 我不确定如何实现这些功能,因此非常感谢您的帮助。

    作为起点,您可能想做的是跟踪用户滚动滚轮的次数。当用户开始触摸方向盘时,使用保存日期和当前角度

    NSDate *lastDate = [NSDate date];
    double lastAngle = //however you're determining the wheel angle
    
    然后在每次触摸移动时,使用当前时间和角度更新这些值。当您最终到达touchEnded时,获取自上次保存日期起的时间间隔,并使用该时间间隔确定车轮的转速:

    NSDate *currentDate = [NSDate date];
    NSTimeInterval elapsedTime = [currentDate timeIntervalSinceDate];
    double rotationalSpeed = (currentAngle - lastAngle) / elapsedTime;
    
    现在你有了轮子在用户手指下旋转的角度/秒。我们的目标是保持相同的速度,因此也许只需启动一个计时器,每隔几秒钟启动一次,然后将车轮旋转到旋转速度*TimeElapsedSincellastTimerFired。通过保存实际日期计算最后一次计时器触发方法的调用方式与上面跟踪车轮角度更新之间的时间的方式类似。或者,可以在角度更新之间有较长的间隔,并随时间设置旋转动画。当您的短动画完成后,您只需开始另一个动画

    这将使车轮无限期地以用户的最后速度转动。为了减少它,你可以有一个定时器,每0.1秒或者其他什么时间触发一次,然后降低旋转速度,直到它达到或低于零。更好的办法是,存储用户松开方向盘的日期,然后根据用户停止交互的时间长短应用一部分旋转速度。比如:

    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];
    }
    
    停止控制盘时,只需确定最近的捕捉点,并将控制盘设置为该位置的动画。你应该在touchesbreated中添加一些东西,当用户触摸轮子时,这些计时器和动画基本上都会结束,这样它就不会在轮子下面产生动画


    我不确定这是否是最优雅的解决方案,但如果我试图解决这个问题,我会从这里开始。祝你好运

    谢谢你,阿提克斯。这给了我一些值得思考的好信息。你最终是如何做到这一点的?:)