Конфликты жестов TableView и PKRevealController — как их решить?

Я пытаюсь реализовать представление со скользящими боковыми меню, например с PKRevealController в iOS 6.1. Простая демонстрация этой проблемы с исходным кодом на github находится здесь, однако вам может не понадобиться ее скачивать если вы уже понимаете реализацию делегатаgestRecognizer.

Проблема, которую я вижу, заключается в том, что два жеста, которые захотят использовать мои пользователи, будут взаимно перепутаны друг с другом. UITableView в центре (главный экран) приложения должен иметь возможность использовать жест пролистывания вправо для удаления, но я все еще хочу, чтобы пролистывание, которое происходит по верхней области навигации, приводило к отображению боковых меню. Я также намереваюсь отображать не только табличное представление, а во время выполнения я планирую заменять основное представление другим представлением всякий раз, когда пользователь выбирает кнопку в одном из боковых меню. Это похоже на «скрытый боковой лоток UITabBarController», который я ищу, но я хочу, чтобы боковые панели отображались только тогда, когда основной контроллер «переднего вида» НЕ является UITableView или его подвидами.

Прямо сейчас, используя демонстрационные исходные коды, поставляемые с PKRevealController, и добавляя поддержку удаления в UITableView основного представления, жест слайда для удаления строки невозможен. (Вы должны добавить один метод табличного представления, чтобы включить поддержку удаления в представлении UITable, которое я добавил.)

Это было задано здесь, но указанный ответ является неполным и, как показано ниже, действительно не работает для меня, и я понятия не имею, почему, потому что кажется, что этот метод делегата не вызывается в любое время, когда я возвращаю YES, и тем не менее он все равно продолжается и начинает жест. Обновить Ответ на предыдущий вопрос также неверен по сравнению с ответом WIKI/FAQ, который я разместил ниже.

Я только изменил класс PKRevealController.m, добавив это:

- (BOOL)                             gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {

    UIView *view1 = otherGestureRecognizer.view;
    UIView *view2;
    if (view1) {
         view2 = view1.superview;
    };

    if ([gestureRecognizer.view isKindOfClass:[UITableView class]])
    {
        return NO;
    }
    // Co-operate by not stealing gestures from UITableView.
    if ([view1 isKindOfClass:[UITableView class]]) {
        return NO;
    }else if ([view1 isKindOfClass:[UITableViewCell class]]) {
        return NO;
        // UITableViewCellContentView
    }
    else if (view2 && [view2 isKindOfClass:[UITableViewCell class]]) {
        return NO;
        // UITableViewCellContentView
    }
    else
    {
        return YES;    // NEVER GETS HIT. BREAKPOINT HERE!
    }
}

Что меня смущает, так это то, что приведенный выше код возврата YES ни разу не срабатывает (у меня есть точка останова на нем), и тем не менее контроллер жестов все еще крадет жест.

Примечание: я сделал злой взлом, но я думал, что смогу предотвратить это чисто. Вот мой злой хак:

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    if (gestureRecognizer == self.revealPanGestureRecognizer)
    {
        CGPoint translation = [self.revealPanGestureRecognizer translationInView:self.frontViewContainer];
        BOOL begin = (fabs(translation.x) >= fabs(translation.y));

        // BEGIN EVIL HACK
        if (_topLimitY > 0) {
         CGPoint location = [gestureRecognizer locationInView:gestureRecognizer.view];
         if (location.y>_topLimitY) // _topLimitY = 55 for instance.
            begin = NO;
        }
        // END EVIL HACK.

        return begin;
    }
    else if (gestureRecognizer == self.revealResetTapGestureRecognizer)
    {
        return ([self isLeftViewVisible] || [self isRightViewVisible]);
    } 

    return YES;
}

Прямо сейчас в моей взломанной демонстрации я установил для свойства topLimitY (которое я добавил в свойства PKRevealController) значение 55, что позволяет мне проводить пальцем по области панели навигации в виде спереди, но не в виде таблицы, которая занимает остальная часть демо.

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

введите здесь описание изображения


person Warren P    schedule 04.04.2013    source источник


Ответы (2)


Я действительно должен сначала прочитать WIKI, не так ли?

Это часто задаваемые вопросы, так правильно сказано -проведите" rel="nofollow">здесь:

При создании экземпляра контроллера передайте этот параметр в свой словарь параметров:

  NSDictionary *options = @{
      PKRevealControllerRecognizesPanningOnFrontViewKey : @NO
  };

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

  [self.navigationController.navigationBar addGestureRecognizer:self.revealController.revealPanGestureRecognizer];

И вуаля — панорамирование больше не мешает просмотру таблицы.

дополнительная информация: https://github.com/pkluz/PKRevealController/issues/76

Спасибо Вики. Если бы я сначала прочитал все это.

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

Обновить Если описанная выше вещь не работает, когда вы пытаетесь это сделать, вероятно, это делается слишком рано. Вот немного более надежная версия вышеуказанного исправления:

// Additional gesture recognition linkups. The underscore variables here
// are implementation-section ivars in my app-delegate,  that I have already 
// checked are valid and initialized, and this is the last thing in my app delegate
// didFinishLaunch... method, before the return YES:

UIGestureRecognizer *rec = _revealController.revealPanGestureRecognizer;
if (rec) {
    [_frontViewNavController.navigationBar addGestureRecognizer:rec];
}
person Warren P    schedule 05.04.2013

Использовать этот :

self.revealController.frontViewController.revealController.recognizesPanningOnFrontView = YES;
person Sanoj    schedule 07.06.2013