UIPanGestureRecognizer для tableView не прокручивает элементы таблицы - PullRequest
0 голосов
/ 31 мая 2018

Использование UIPanGesture на UITableView (Swift 4.0) для перетаскивания позиции просмотра таблицы (то есть начала координат).UIPanGestureRecognizer обнаружение сенсорных событий и их использование.В какой-то момент я хочу делегировать события в таблицу, чтобы она прокручивала свои элементы.Как я могу это сделать?

Что я пробовал:

@objc func tableViewDragged(gestureRecognizer: UIPanGestureRecognizer) {

        if gestureRecognizer.state == UIGestureRecognizerState.began || gestureRecognizer.state == UIGestureRecognizerState.changed {

            let translation = gestureRecognizer.translation(in: self.view)

// if origin moved to map origin it should not scroll above but cell should scroll normally. But returning does not help scrolling cells
            if self.tableView.frame.origin == self.mapContainer.frame.origin && translation.y < 0 {

                return
            }

            var frame = self.tableView.frame
            let nHeight = (frame.origin.y + translation.y)

            if (nHeight < self.view.frame.size.height) {

                frame.origin.y = nHeight
                self.tableView.frame = frame
                gestureRecognizer.setTranslation(CGPoint(x: 0, y: 0), in: self.view)
            }
        }
}

Жест добавлен в tableView

let gesture = UIPanGestureRecognizer(target: self, action: #selector(self.tableViewDragged(gestureRecognizer:)))
self.tableView.addGestureRecognizer(gesture)
self.tableView.isUserInteractionEnabled = true
gesture.delegate = self

Краткое описание проблемы:

Для одного и того же жеста панорамирования в любой точке просмотра таблицы (т.е. в любой ячейке)Мне нужно прокрутить элементы, когда происхождение табличных представлений будет зафиксировано в верхнем левом углу контейнера.В противном случае мне придется перемещать табличное представление, пока оно не будет прикреплено к верхней левой точке.Более того, если нечего прокручивать, мне нужно снова переместить таблицу ниже для жеста панорамирования.

* Неисправности Варианты использования: *

  1. исходное условие - просмотр таблицыначало координат находится в середине экрана, т. е. (0, высота / 2)
  2. жест панорамирования - таблица перемещается вертикально вверх, но элементы не прокручиваются, пока источник не застрянет в (0,0)
  3. жест панорамирования - элементы ячейки перемещены вверх, но не сама таблица
  4. жест панорамирования - элементы ячейки перемещены вверх до конца ячеек
  5. жест панорамирования - элементы ячейки перемещены вниз до индекса 0, скажем, дошел до 0 index
  6. жест панорамирования - просмотр таблицы перемещался вертикально вниз, пока его начало не достигло середины экрана (0, высота / 2)

Ответы [ 3 ]

0 голосов
/ 31 мая 2018

Если я правильно понимаю, поэтому вы хотите отменить PanGesture, когда хотите прокрутить.

Попробуйте:

func isItemAvailabe(gesture: UISwipeGestureRecognizer) -> Bool {
    if gesture.direction == .down {
        // check if we have some values in down if yes return true else false
    } else if gesture.direction == .up {
        // check if we have some values in up if yes return true else false
    }
    return false
}

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,
                       shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    if gestureRecognizer == self.panGesture && otherGestureRecognizer == self.scrollGesture && isItemAvailabe(gesture: otherGestureRecognizer) {
        return true
    }
    return false
}

Дайте мне знать, если это решит вашу проблему, или яне получается правильно.

Также не забудьте добавить это тоже:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}

Вы можете проверить больше здесь

0 голосов
/ 31 мая 2018

Лучший способ сделать это, используя собственный panGestureRecognizer tableView (без добавления нового gestRecognizer), например:

tableView.panGestureRecognizer.addTarget(self, action: #selector(self.tableViewDragged(gestureRecognizer:))

Действие

@objc func tableViewDragged(gestureRecognizer: UIPanGestureRecognizer) {
    guard tableView.contentOffset.y < 0 else { return }
    if gestureRecognizer.state == UIGestureRecognizerState.began || gestureRecognizer.state == UIGestureRecognizerState.changed {

    let translation = gestureRecognizer.translation(in: self.view)

    // if origin moved to map origin it should not scroll above but cell should scroll normally. But returning does not help scrolling cells
    if self.tableView.frame.origin == self.mapContainer.frame.origin && translation.y < 0 {

        return
    }

    var frame = self.tableView.frame
    let nHeight = (frame.origin.y + translation.y)

    if (nHeight < self.view.frame.size.height) {

        frame.origin.y = nHeight
        self.tableView.frame = frame
        gestureRecognizer.setTranslation(CGPoint(x: 0, y: 0), in: self.view)
    }
}
}
0 голосов
/ 31 мая 2018

Я не знаю лучшего решения, чем создание подкласса вашего tableView и блокирование его contentOffset в layoutSubviews его.Примерно так:

class MyTableView: UITableView {
    var blocksOffsetAtZero = false
    override func layoutSubviews() {
        super.layoutSubviews()
        guard blocksOffsetAtZero else { return }
        contentOffset = .zero
    }
}

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

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

ОБНОВЛЕНИЕ https://github.com/gaetanzanella/mapLike

Правильно ли реализован делегат?

// MARK: - UIGestureRecognizerDelegate

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,
                       shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}

Попробуйте что-то вроде:

@objc func tableViewDragged(gestureRecognizer: UIPanGestureRecognizer) {

    if gestureRecognizer.state == UIGestureRecognizerState.began || gestureRecognizer.state == UIGestureRecognizerState.changed {

        let translation = gestureRecognizer.translation(in: self.view)

        var frame = self.tableView.frame
        let nHeight = (frame.origin.y + translation.y)

        if (nHeight < self.view.frame.size.height) {
            frame.origin.y = nHeight
            self.tableView.frame = frame
            gestureRecognizer.setTranslation(CGPoint(x: 0, y: 0), in: self.view)
            tableView.blocksOffsetAtZero = true
        } else {
            tableView.blocksOffsetAtZero = false
        }
    }
}

Основная идея: когда вы меняете кадр, блокируйте прокрутку.

Вы также можете использовать технику делегата, представленную kamaldeep singh bhatia, но вы не сможете переместить первый tableView, а затем прокрутить одним жестом.

См. Пример здесь

...