В качестве отправной точки, вы, вероятно, захотите сделать, чтобы отслеживать, сколько пользователь прокручивал колесо.Когда пользователь начинает касаться колеса, сохраните дату и текущий угол с помощью
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;
Теперь у вас есть угол / секунда, под которой колесо вращается подпалец пользователя.Цель состоит в том, чтобы поддерживать ту же скорость, поэтому, возможно, просто запустив таймер, который срабатывает каждую долю секунды и поворачивает колесо в вращениеSpeed * timeElapsedSinceLastTimerFired.Вычислите последнее, сохранив фактическую дату, когда вызванный таймер метод вызывается аналогично тому, как вы отслеживали время между обновлениями угла поворота колеса выше.Кроме того, вы можете иметь более длинные интервалы между обновлениями угла и анимировать вращение с течением времени.Когда ваша короткая анимация завершится, вы просто начнете другую.
Они будут держать колесо вращаться на последней скорости пользователя бесконечно.Чтобы сузить его, у вас может быть просто таймер, который срабатывает каждые 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];
}
Когда вы останавливаете колесо, просто определите, какая точка привязки находится ближе всего, и анимируйте колесо в это положение.Вы должны добавить что-то в touchesBegan, которое в основном завершает все эти таймеры и анимацию, когда пользователь также касается колеса, чтобы оно не анимировалось под ним.
Я не уверен, что это самое элегантное решение,но это то, с чего бы я начал, если бы попытался решить проблему.Удачи!