Непрерывная прокрутка между UIPanGestureRecognizer и повторно включенным UIScrollView

У меня есть UIScrollView с включенным пейджингом, и я добавил к нему свой собственный UIPanGestureRegonizer. В некоторых случаях мой контроллер представления установит scrollview.scrollEnabled = NO, а затем добавит к нему распознаватель жестов панорамирования (я не использую собственный распознаватель прокрутки).

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

Проблема в том, что пока пользователь все еще держит палец, моя прокрутка не отслеживает палец. Прокрутка не начинается до тех пор, пока палец не будет поднят, а затем снова перетащен. Итак, мой распознаватель жестов поглощает все прикосновения и не перенаправляет их в прокрутку.

Я пытался переключить panGestureRecognizer.cancelsTouchesInView = NO;, но, похоже, это не имеет никакого эффекта (в настоящее время я удаляю этот распознаватель, как только снова включаю прокрутку, но независимо от того, делаю я это или нет, моя проблема не решается). Я также просмотрел delays... свойства UIGestureRecognizer, но они, похоже, тоже не помогают.

Любые идеи? Как я могу заставить эти события продолжать пересылаться на мой прокрутку?


person jbrennan    schedule 03.01.2012    source источник
comment
Вы пытались вернуть YES в методе gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:?   -  person Hejazi    schedule 04.01.2012
comment
@Hejazi Да, я тоже реализовал этот метод делегата (и установил свой делегат), но он не вызывается, пока палец все еще опущен (только после того, как я снова поднял и опустил палец, этот метод делегата вызывается).   -  person jbrennan    schedule 04.01.2012


Ответы (1)


Ответ немного проще, если вы ориентируетесь только на iOS 5 и выше, потому что в этом случае вам действительно следует повторно использовать свойство UIScrollView panGestureRecognizer.

В любом случае, ключевым шагом является НЕ повторное использование scrollEnabled, а вместо этого создание подкласса UIScrollView, создание собственного свойства для управления этим состоянием и переопределение setContentOffset:.

    - (void) setContentOffset:(CGPoint)contentOffset
    {
        if(self.programaticScrollEnabled)
            [super setContentOffset:contentOffset];
    }

Вот одно из возможных решений iOS 4+:

  1. Подкласс UIScrollView (или подкласс другого подкласса UIScrollView, в зависимости от ваших потребностей).
  2. Переопределите все инициализаторы, чтобы обеспечить вызов вашего кода установки.
  3. Объявите свойство BOOL и переопределите setContentOffset: как описано выше.
  4. В своем коде установки настройте UIPanGestureRecognizer и установите переменную состояния, чтобы разрешить программную прокрутку (при условии, что это состояние по умолчанию, которое вы хотите):

    panRecognizer = [[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)] autorelease];
    //These properties may change according to your needs
    panRecognizer.cancelsTouchesInView = NO;
    panRecognizer.delaysTouchesBegan = NO;
    panRecognizer.delaysTouchesEnded = NO;
    [self addGestureRecognizer:panRecognizer];
    panRecognizer.delegate = self;
    
    self.programaticScrollEnabled = YES;
    
  5. Управляйте тем, какие жесты могут выполняться одновременно. В моем случае:

    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
    {
        return YES;
    }
    
  6. Включите программную прокрутку, где вам это нужно. Например:

    - (void)handleGesture:(UIPanGestureRecognizer *)gestureRecognizer
    {
        self.programaticScrollEnabled = YES;
    }
    
    - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
    {
        self.programaticScrollEnabled = YES;
        return YES;
    }
    
person Prometheus    schedule 25.01.2012