1

我有 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)
        })
    }
}

还实现了以下委托,因为当 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 的滚动。

任何人都可以提供解决方案吗?

先感谢您。

4

1 回答 1

2

您可以尝试通过以下方法处理手势识别器。通过这样做,您可以在找到附加的视图手势和手势类型后实现向下拖动以关闭功能。

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
    }

}

于 2020-02-07T12:00:33.090 回答