Обнаружение горизонтального панорамирования в UITableView - PullRequest
30 голосов
/ 25 марта 2011

Я использую UIPanGestureRecognizer для распознавания горизонтального скольжения в UITableView (точнее, в ячейке, хотя она добавляется в саму таблицу). Однако этот распознаватель жестов, очевидно, крадет штрихи со стола. Я уже получил распознаватель pangesture для распознавания горизонтального скольжения и затем привязки к нему; но если пользователь начинает с скольжения по вертикали, он должен передать все события от этого прикосновения к табличному виду.

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

Еще одна вещь, которую я пытался сделать, это прокручивать себя, но тогда вы потеряете постоянную скорость после остановки касания.

Вот какой-то код:

//In the viewdidload method
UIPanGestureRecognizer *slideRecognizer = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(sliding:)];
[myTable addGestureRecognizer:slideRecognizer];



-(void)sliding:(UIPanGestureRecognizer *)recognizer
{
    if (recognizer.state == UIGestureRecognizerStateBegan)
    {
    CGPoint translation = [recognizer translationInView:favoritesTable];
    if (sqrt(translation.x*translation.x)/sqrt(translation.y*translation.y)>1) {
        horizontalScrolling = YES; //BOOL declared in the header file
        NSLog(@"horizontal");
        //And some code to determine what cell is being scrolled:
        CGPoint slideLocation = [recognizer locationInView:myTable];
        slidingCell = [myTable indexPathForRowAtPoint:slideLocation];
        if (slidingCell.row == 0) {
            slidingCell = nil;
        }

    }
    else
    {
        NSLog(@"cancel");
    }

    if (recognizer.state == UIGestureRecognizerStateEnded || recognizer.state == UIGestureRecognizerStateCancelled)
    {
    horizontalScrolling = NO;
    }


    if (horizontalScrolling)
    {
        //Perform some code
    }
    else
    {
    //Maybe pass the touch from here; It's panning vertically
    }

}

Итак, есть ли советы о том, как передать прикосновения?

Дополнение: я также подумал, что, возможно, создам подкласс метода распознавания жестов в табличном представлении, чтобы сначала проверить, является ли он горизонтальным; Однако тогда мне понадобится оригинальный код, я полагаю ... Не знаю, возникнут ли у Apple проблемы с ним. Кроме того: я не делил подкласс UITableView (контроллер), только клетки. Этот код находится в viewcontroller, который содержит таблицу;)

Ответы [ 5 ]

56 голосов
/ 19 августа 2011

У меня была та же проблема, и я нашел решение, которое работает с UIPanGestureRecognizer.

В отличие от Эрика, я добавил UIPanGestureRecognizer непосредственно в ячейку, так как мне нужна только одна конкретная ячейка одновременно для поддержки панорамирования.Но я думаю, это должно сработать и в случае Эрика.

Вот код.

- (BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gestureRecognizer
{
    UIView *cell = [gestureRecognizer view];
    CGPoint translation = [gestureRecognizer translationInView:[cell superview]];

    // Check for horizontal gesture
    if (fabsf(translation.x) > fabsf(translation.y))
    {
        return YES;
    }

    return NO;
}

Расчет горизонтального жеста скопирован из кода Эрика - я проверял это с iOS 4.3.

Редактировать: Я обнаружил, что эта реализация предотвращает жест "смахивание-удаление".Чтобы восстановить это поведение, я добавил проверку скорости жеста в оператор if, приведенный выше.

if ([gestureRecognizer velocityInView:cell].x < 600 && sqrt(translate...

Немного поиграв на своем устройстве, я получил скорость от 500 до 600, которая предлагаетна мой взгляд, лучший пользовательский интерфейс для перехода между панорамированием и жестом смахивания для удаления.

6 голосов
/ 14 июня 2014

Мой ответ такой же, как у Флориана Мильке, но я несколько упростил и исправил его.

Как использовать:

Просто дайте вашему UIPanGestureRecognizer делегату (UIGestureRecognizerDelegate).Например:

UIPanGestureRecognizer *panner = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panDetected:)];
panner.delegate = self;
[self addGestureRecognizer:panner];

Затем этот делегат реализует следующий метод:

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    CGPoint translation = [(UIPanGestureRecognizer *)gestureRecognizer translationInView:gestureRecognizer.view.superview];
    return fabsf(translation.x) > fabsf(translation.y);
}
1 голос
/ 25 марта 2011

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

Каждый класс, который наследуется от UIResponder, будет иметь четыре сенсорные функции (начало, окончание, отмена и перемещение). Таким образом, самый простой способ «переслать» вызов - это обработать его в вашем классе и затем явно вызвать его для следующего объекта, который вы хотите обработать (но вы должны убедиться, что объект сначала отвечает на сообщение RespondsToSelector: так как это необязательная функция). Таким образом, вы можете обнаружить любые события, которые вы хотите, а также разрешить нормальное взаимодействие с сенсорным экраном, когда это понадобится другим элементам.

0 голосов
/ 25 марта 2011

Спасибо за советы!В конце концов я выбрал подкласс UITableView, где я проверяю, является ли движение горизонтальным (в этом случае я использую свое собственное поведение), и еще вызываю [super touchesMoved: withEvent:];

Однако я до сих пор не понимаю, почему это работает.Я проверил, и супер это UITableView.Похоже, я все еще не до конца понимаю, как работает эта иерархия.Может кто-нибудь попытаться объяснить?

0 голосов
/ 25 марта 2011

Может быть, вы можете использовать вместо UISwipeGestureRecognizer? Вы можете указать игнорировать пролистывание вверх / вниз через свойство direction.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...