Меню iPhone в стиле руля - PullRequest
       12

Меню iPhone в стиле руля

1 голос
/ 21 ноября 2010

Я хотел бы создать меню в стиле колеса, которое позволяет пользователю вращать колесо (UIImageView), чтобы увидеть различные варианты. В верхней половине колеса также есть индикатор выбора, и пользователь может выбрать конкретный параметр, перетаскивая нужный параметр вокруг колеса и положения под индикатором выбора (как при использовании UIPickerView).

После публикации SO iPhone - Как построить колесо, похожее на рулетку? Мне удалось реализовать колесо, которое отслеживает прикосновения пользователя и соответственно вращает колесо. Однако мне нужны две дополнительные функции:

  1. Реализовать инерционную прокрутку, чтобы пользователь мог совершать движение по колесу, и оно вращалось и изящно замедлялось / замедлялось, немного похоже на колесо в игровом шоу "Колесо фортуны".

  2. Когда колесо заканчивает замедляться и полностью останавливается, оно автоматически останавливается на одном из параметров, так что под индикатором выбора отображается один параметр (например, UIPickerView), вместо того, чтобы потенциально иметь два варианта обе половины под индикатором выбора.

Я не уверен, как реализовать эти функции, поэтому любая помощь будет принята с благодарностью.

1 Ответ

2 голосов
/ 21 ноября 2010

В качестве отправной точки, вы, вероятно, захотите сделать, чтобы отслеживать, сколько пользователь прокручивал колесо.Когда пользователь начинает касаться колеса, сохраните дату и текущий угол с помощью

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, которое в основном завершает все эти таймеры и анимацию, когда пользователь также касается колеса, чтобы оно не анимировалось под ним.

Я не уверен, что это самое элегантное решение,но это то, с чего бы я начал, если бы попытался решить проблему.Удачи!

...