Нужно ли использовать UIPanGestureRecognizer вместо UISwipeGestureRecognizer, если я хочу отслеживать движение?

Я пытаюсь реализовать пейджинговое взаимодействие для одного из моих представлений. Я думал, что просто использую UISwipeGestureRecognizers. Но путем проб и ошибок, а также изучения документации оказалось, что

Смахивание — это дискретный жест, поэтому связанное с ним сообщение о действии отправляется только один раз для каждого жеста.

Таким образом, хотя я мог вызвать страницу, я не смог бы подключить анимацию, которая возникла во время перетаскивания.

Является ли моя единственная альтернатива использованию UIPanGestureRecognizer и повторной реализации базовой фильтрации/вычислений салфетки?

Обновление/сокращение

Оглядываясь назад, я действительно должен был спросить, как реализовать жест «щелчок». Если вы не собираетесь создавать свой собственный подкласс (можете немного его откусить), вы используете UIPanGestureRecognizer, как указывает ответ @Lyndsey. Что я искал после этого (в комментариях), так это то, как сделать часть щелчка, где импульс щелчка влияет на решение о том, продолжать ли движение щелчка или возвращаться к исходной презентации.

UIScrollView имеет такое поведение, и заманчиво изучить его реализацию для получения подробной информации о том, как можно замедлить импульс таким образом, чтобы это было согласованным, но, увы, decelerationRate, предоставленное для UIScrollView, является значением «за итерацию» (согласно некоторым). Я ломал голову над тем, как правильно применить значение по умолчанию 0,998 к конечной скорости панорамирования.

В конце концов, я использовал код, взятый с сайтов о вычислении «щелчка», и сделал что-то вроде этого в своем обработчике жестов:

...
else if (pan.state == UIGestureRecognizerStateEnded) {
    CGFloat v = [pan velocityInView: self.view].x;
    CGFloat a = -4000.0; // 4 pixels/millisecond, recommended on gavedev
    CGFloat decelDisplacement = -(v * v) / (2 * a); // physics 101
    // how far have we come plus how far will momentum carry us?
    CGFloat totalDisplacement = ABS(translation) + decelDisplacement;
    // if that is (or will be) half way across our view, finish the transition
    if (totalDisplacement >= self.view.bounds.size.width / 2) {
        // how much time would we need to carry remainder across view with current velocity and existing displacement? (capped)
        CGFloat travelTime = MIN(0.4, (self.view.bounds.size.width - ABS(translation)) * 2 / ABS(v));
        [UIView animateWithDuration: travelTime delay: 0.0 options: UIViewAnimationOptionCurveEaseOut animations:^{
            // target/end animation positions
        } completion:^(BOOL finished) {
            if (finished) {
                // any final state change
            }
        }];
    }
    else { // put everything back the way it was
        ...
    }
}

person Travis Griggs    schedule 21.11.2014    source источник
comment
Да, используйте UIPanGestureRecognizer, если вы хотите, чтобы определенная скорость, угол, изменения и т. д. смахивания запускали вашу анимацию. UISwipeGestureRecognizer — это действительно один дискретный жест... похожий на UITapGestureRecognizer.   -  person Lyndsey Scott    schedule 22.11.2014
comment
Вздох. Есть ли какая-либо документация о том, что нужно делать, чтобы правильно эмулировать направленную фильтрацию и скорость?   -  person Travis Griggs    schedule 22.11.2014
comment
К вашему сведению, я разместил ссылки на документацию в своем ответе ниже.   -  person Lyndsey Scott    schedule 24.11.2014


Ответы (1)


Да, используйте UIPanGestureRecognizer, если вы хотите, чтобы конкретная скорость, угол, изменения и т. д. «пролистывания» запускали вашу анимацию. UISwipeGestureRecognizer — это действительно один дискретный жест; подобно UITapGestureRecognizer, при распознавании вызывает одно сообщение о действии.

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

person Lyndsey Scott    schedule 21.11.2014
comment
Я хотел бы выяснить, где закончится мой удар. Во время события Ended у меня есть текущее смещение, а также скорость. Но я не знаю, что использовать в качестве коэффициента замедления, чтобы вычислить, как далеко меня унесет эта конечная скорость. Публикует ли Apple что-нибудь о том, что они используют для этих вычислений? - person Travis Griggs; 24.11.2014
comment
@TravisGriggs Что ты имеешь в виду под понесет меня? Вы просто хотите знать, где оказался палец пользователя? Если это так, нет необходимости делать какие-либо вычисления. Просто используйте locationInView:: developer.apple.com/library/ios/documentation/UIKit/reference/: - person Lyndsey Scott; 24.11.2014
comment
Нет, это немного сложнее, чем просто locationInView:. Это просто говорит мне, где закончилось смахивание (панорамирование). Учитывая, что я использую пролистывание для просмотра страницы, мне нужно выяснить, насколько далеко было бы пролистывание представления, чтобы решить, достаточно ли этого для перехода на следующую страницу. Если пользователь сильно щелкает по экрану, важно не только перемещение пальца, но и то, насколько далеко будет перемещаться вид с учетом скорости движения во время отрыва. Вы видите это с представлениями прокрутки Apple. Я надеялся на некоторые подсказки, как они это делают. - person Travis Griggs; 26.11.2014
comment
О, вы проводите пальцем по UIScrollView? Просто проверьте смещение его содержимого после завершения прокрутки, чтобы узнать его окончательное положение. - person Lyndsey Scott; 26.11.2014
comment
Нет, я не провожу пальцем по UIScrollView. Но я пытаюсь получить что-то похожее на UIScrollView скольжение с обычными UIView и UIPanGestureRecognizer. - person Travis Griggs; 26.11.2014