Подтвердить что ты не робот

Обнаружить горизонтальное панорамирование в UITableView

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

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

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

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

//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 panning vertically
    }

}

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

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

4b9b3361

Ответ 1

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

В отличие от Erik я добавил 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;
}

Вычисление горизонтального жеста копируется из кода Erik - я тестировал это с помощью iOS 4.3.

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

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

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

Ответ 2

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

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

Просто передайте 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);
}

Ответ 3

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

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

Ответ 4

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

Ответ 5

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

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