Предсказание смещения покоя в UIScrollView после замедления
Я хотел бы иметь возможность предсказать окончательное смещение покоя в UIScrollView после жестов flick. Он не должен быть точным, точным, но достаточно близким, чтобы пользователь не воспринимал разницу (т.е. Он не перемещался слишком мало или больше, чем они используются).
Я знаю, что кто-то спросит, так: Почему? В UIScrollView есть элемент управления, похожий на таблицу. Я хотел бы сделать так, чтобы верхний пункт меню полностью отображался и выравнивался до вершины UIScrollView. Функция пейджинга UIScrollView не совсем то, что я хочу, потому что сильный щелчок не пролетает мимо кратных оценок.
Обработка обычных событий касания достаточно проста. На touchesEnded:withEvent:
я могу прокрутить до ближайшего пункта полного меню. Тяжелая часть - это замедление.
Существуют две константы для скорости торможения, UIScrollViewDecelerationRateNormal
и UIScrollViewDecelerationRateFast
. Их значения равны 0.998 и 0.990 в iPhone OS 3.0. Я попытался выяснить математику, которую использует Apple для замедления движения, но я прихожу пустым.
Если я могу с некоторой точностью предсказать окончательное смещение покоя, то раньше во время замедления я могу просто использовать scrollRectToVisible:animated:
для перемещения к смещению с элементом меню, скрытым в верхней части границ обзора.
Знают ли люди, склонные к математике, что Apple может делать во время замедления? Должен ли я собирать кучу чисел событий замедления, нарисуйте их и придумайте что-нибудь близкое?
Ответы
Ответ 1
Контроль UIScrollView targetContentOffset в iOS 5
iOS5 UIScrollViewDelegate
имеет новый метод: scrollViewWillEndDragging:withVelocity:targetContentOffset:
.
Это идеально подходит для того, что вы хотите сделать.
Этот метод не вызывается, когда значение просмотров прокрутки Свойство pagingEnabled - ДА. Ваше приложение может изменить значение параметра targetContentOffset, чтобы настроить, где scrollview завершает свою прокрутку анимации.
Альтернативное решение для iOS4 и ниже
Измените UIScrollView
decelerationRate
на UIScrollViewDecelerationFast
, а затем в scrollViewDidEndDecelerating
перейдите на ближайшую "страницу".
Быстрое замедление делает полную остановку/скольжение более естественным/менее неприятным.
Ответ 2
Вы можете наблюдать скорость прокрутки, пока UIScrollView замедляется, а когда скорость падает ниже определенного значения, привязывайтесь к ближайшему пункту меню.
Скорее всего, вы захотите реализовать UIScrollViewDelegate
методы scrollViewDidEndDragging:willDecelerate:
и scrollViewDidScroll:
. Когда пользователь поднимает палец, чтобы закончить жест прокрутки, будет вызван scrollViewDidEndDragging:willDecelerate:
. Начните отслеживать события scrollViewDidScroll:
и наблюдайте дельта между текущей позицией UIScrollView
и ее предыдущей позицией, деленной на дельта времени:
float velocity = (currentPosition - lastPosition) / (currentTime - lastTime);
Когда скорость опускается ниже минимального значения, вызовите scrollRectToVisible:animated:
на UIScrollView
.
Ответ 3
Я не могу комментировать (я думаю, мне нужно 50 rep), так что это не полный ответ, но с учетом значений 0.998 и 0.990 для замедления мои инстинкты состоят в том, что они просто умножают текущую скорость на скорость торможения каждого кадра.