Пейджинг UIScrollView с двумя пальцами панорамирования и масштабирования - PullRequest
7 голосов
/ 06 ноября 2011

Контрольный пример легко воспроизводится: загрузите образец приложения Apple PhotoScroller и попробуйте адаптировать его так, чтобы панорамирование (как вокруг увеличенного изображения, так и между каждым изображением) работало только двумя пальцами.

Установка panGestureRecognizer для pagingScrollView и imageScrollView для принятия только минимума и максимума в 2 касания кажется хорошим местом для начала, однако это не работает.Это позволяет вам просто прокручивать изображение двумя пальцами *, однако подкачка тогда не работает.

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

* РЕДАКТИРОВАТЬ: На самом деле, это не прокручивается нормально в этой ситуации.Изображение больше не скользит гладко, как при одном касании ...

ОБНОВЛЕНИЕ: Я все еще борюсь с этим.Я был бы признателен за информацию от кого-то, кто играл с UIGestureRecognizer s и UIScrollView s.

EDIT :

Установка ImageScrollViewКласс допускает только два касания:

- (id)initWithFrame:(CGRect)frame
{
    // ...
    // Template code
    // ...

    [self.panGestureRecognizer setMinimumNumberOfTouches:2];
    [self.panGestureRecognizer setMaximumNumberOfTouches:2];
}

Установка PhotoViewController pagingScrollView для принятия только двух касаний:

- (void)loadView
{
    // ...
    // Template code
    // ...

    [pagingScrollView.panGestureRecognizer setMinimumNumberOfTouches:2];
    [pagingScrollView.panGestureRecognizer setMaximumNumberOfTouches:2];
}

Эти модификации выполняются непосредственно поверх PhotoScrollerпример приложения.Я ожидаю, что эти простые изменения будут работать для взаимодействия двумя пальцами, однако побочные эффекты являются странными (как объяснено выше).

Ответы [ 3 ]

1 голос
/ 16 октября 2016

ПРОБЛЕМА :

Когда UIPanGestureRecognizer лежит в основе UIScrollView (что, к сожалению, делаеттакже влияет UIPageViewController) maximumNumberOfTouches не работает должным образом - minimumNumberOfTouches однако всегда ограничивает нижний пределправильно.

При мониторинге этих параметров они, кажется, выполняют свою работу - просто UIScrollView не соблюдает их и игнорирует их значения!


REMEDY :

Вы можете найти решение в моем ответе на:

UIScrollView, прокрутка только одним пальцем


КСТАТИ:

Разница между one finger и two panning состоит в том, чтоодним пальцем вы используете panGestureRecognizer.Двумя пальцами включается pinchGestureRecognizer (который также может панорамироваться одновременно), и у вас нет фазы замедления, и изображение прекращает панорамирование и масштабирование сразу после отпускания пальцев.Отключите pinchGestureRecognizer, и вы увидите, что panGestureRecognizer вступает во владение - даже для двух пальцев - и панорамирование снова становится плавным ... ;-)


ОДНОВРЕМЕННО -et voilà ...

Делегирование обратных вызовов для идеального одновременного поведения двумя пальцами scrolling и zooming:

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    self.pinchGestureRecognizer.enabled = NO;
}

- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView {
    self.pinchGestureRecognizer.enabled = NO;
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
    self.pinchGestureRecognizer.enabled = YES;
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    self.pinchGestureRecognizer.enabled = YES;
}

- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view {    
    self.panGestureRecognizer.enabled = NO;
}

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale {    
    self.panGestureRecognizer.enabled = YES;
}

Fast pinch начинает масштабирование!
Fast pan начинает панорамирование!

Остановка замедляющей сковородки двумя новыми пальцами вниз на экране и повторное перетаскивание не позволяют неуклюжимpinchGestureRecognizer вступает во владение (по умолчанию), но довольно плавно переходит в следующую фазу панорамирования / замедления - как одним пальцем!


ДЛЯ ПЕРФЕКТИСТОВ:

Положите 2 пальца на экран и - НЕ ПЕРЕМЕЩАЙТЕ СЕЙЧАС - Если вы не начинаете зажимать в течение первых 0,5 секунд zoomingблокируется и только panning доступно:

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {

    if ([gestureRecognizer.view isMemberOfClass:[MY_CustomScrollView class]]) {

        NSLog(@"IN SCROLL-VIEW...");
        if (gestureRecognizer == self.pinchGestureRecognizer) {
            if (_pinchGestureLocked) {
                NSLog(@"...but TOO late for zooming...");
                return NO;
            } else {
                NSLog(@"...ZOOMING + PANNING...");
                return YES;
            }
        } else if (gestureRecognizer == self.panGestureRecognizer){
            if (gestureRecognizer.numberOfTouches > 2) {
                NSLog(@"...but TOO many touches for PANNING ONLY...");
                return NO;
            } else {
                NSLog(@"...PANNING...");
                return YES;
            }
        } else {

            NSLog(@"...NO PAN or PINCH...");
            return YES;
        }

    } else {
        NSLog(@"NOT IN SCROLL-VIEW...");
    }

    return YES;

}  

BOOL _pinchGestureLocked = NO;

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [super touchesBegan:touches withEvent:event];
    _pinchGestureLocked = YES;
}

- (void) touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [super touchesCancelled:touches withEvent:event];
    _pinchGestureLocked = NO;
}

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [super touchesEnded:touches withEvent:event];
    _pinchGestureLocked = NO;
}

Счастливый жест-рузнавая!


0 голосов
/ 11 января 2013

Может показаться, что это либо невозможно, либо очень очень сложно (например, разверните свой собственный вид прокрутки с нуля).Я использовал инцидент технической поддержки Apple, и они не смогли помочь.Если решение станет доступным, я с радостью отмечу его как принятый ответ!

0 голосов
/ 15 ноября 2011

Подклассы, кажется, способ пойти с этим

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

Описание класса UIScrollView

В частности

Подклассы могут переопределять touchesShouldBegin: withEvent: inContentView :, pagingEnabled и touchesShouldCancelInContentView: методы (которые вызываются представление прокрутки), чтобы указать, как представление прокрутки обрабатывает жесты прокрутки.

Вам также следует взглянуть на этот пост SO, Прокрутка двумя пальцами с помощью UIScrollView

...