Добавление UIPanGesture к UITableView блокирует прокрутку UITableView в Xcode 11.3 - PullRequest
1 голос
/ 15 января 2020

У меня есть UIViewController с UITableView. Я хочу отклонить UIViewController, когда пользователь опускает таблицу. Добавление UIPanGestureRecognizer в представление UIViewController будет работать только в том случае, если содержимое таблицы меньше и таблица не прокручивается. Поэтому я добавил UIPanGestureRecognizer в tableView:

self.detailTableView.bounces = true
let gesture = UIPanGestureRecognizer(target: self, action: #selector(onPan(_:)))
gesture.delegate = self
self.detailTableView.gestureRecognizers = [gesture]

Метод onPan:

@objc func onPan(_ panGesture: UIPanGestureRecognizer) {
    guard self.detailTableView.contentOffset.y <= 0 else {
        return
    }

    func slideViewVerticallyTo(_ yPoint: CGFloat) {
        self.view.frame.origin = CGPoint(x: 0, y: yPoint)
    }

    switch panGesture.state {

    case .began, .changed:
        // If pan started or is ongoing then
        // slide the view to follow the finger
        let translation = panGesture.translation(in: view)
        let yPoint = max(0, translation.y)
        slideViewVerticallyTo(yPoint)

    case .ended:
        // If pan ended, decide it we should close or reset the view
        // based on the final position and the speed of the gesture
        let translation = panGesture.translation(in: view)
        let velocity = panGesture.velocity(in: view)
        let closing = (translation.y > self.view.frame.size.height / 2) ||
            (velocity.y > minimumVelocityToHide)

        if closing {
            UIView.animate(withDuration: animationDuration, animations: {
                // If closing, animate to the bottom of the view
                slideViewVerticallyTo(self.view.frame.size.height)
            }, completion: { (isCompleted) in
                if isCompleted {
                    // Dismiss the view when it disappeared
                    // Dismiss UIViewController here....
                }
            })
        } else {
            // If not closing, reset the view to the top
            UIView.animate(withDuration: animationDuration, animations: {
                slideViewVerticallyTo(0)
            })
        }

    default:
        // If gesture state is undefined, reset the view to the top
        UIView.animate(withDuration: animationDuration, animations: {
            slideViewVerticallyTo(0)
        })
    }
}

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

public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        if let panRecognizer = gestureRecognizer as? UIPanGestureRecognizer {
            // Ensure it's a Vertical drag
            let velocity = panRecognizer.velocity(in: self.view)
            if abs(velocity.y) < abs(velocity.x) {
                return false
            }
        } else {
            return false
        }
        return true
    }

Этот код работал нормально с Xcode 10.2.1. Теперь я обновился до Xcode 11.3, dismiss работает, но он заблокировал прокрутку tableView.

Может кто-нибудь предложить решение?

Заранее спасибо.

1 Ответ

2 голосов
/ 07 февраля 2020

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

extension ViewController: UIGestureRecognizerDelegate {

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {

        if gestureRecognizer.isKind(of: UIPanGestureRecognizer.self) && otherGestureRecognizer.isKind(of: UIPanGestureRecognizer.self) && gestureRecognizer.view == tableview && gestureRecognizer.view == tableview {
            // your logic here
        }
        return true
    }

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool {

        if gestureRecognizer.isKind(of: UIPanGestureRecognizer.self) && otherGestureRecognizer.isKind(of: UIPanGestureRecognizer.self) && gestureRecognizer.view == tableview && gestureRecognizer.view == tableview {
            // your logic here
        }
        return true
    }

}

...