Swift : Pull down to dismiss `UITableViewController` Swift : Pull down to dismiss `UITableViewController` xcode xcode

Swift : Pull down to dismiss `UITableViewController`


You have to implement additional pan gesture recognizer which will recognize simultaneously with scrollView's pan gesture recognizer. Then you can determine whether user is panning by his finger when table view is already scrolled to the top.e.g.

var isTrackingPanLocation = falsevar panGestureRecognizer: UIPanGestureRecognizer!public override func viewDidLoad() {    super.viewDidLoad()    tableView.bounces = false    panGestureRecognizer = UIPanGestureRecognizer(target: self,                                                   action: #selector(panRecognized(gestureRecognizer:)))    panGestureRecognizer.delegate = self    tableView.addGestureRecognizer(panGestureRecognizer)}public func panRecognized(recognizer: UIPanGestureRecognizer) {    if recognizer.state == .began && tableView.contentOffset.y == 0 {        recognizer.setTranslation(CGPoint.zero, inView : tableView)        isTrackingPanLocation = true    } else if recognizer.state != .ended &&               recognizer.state != .cancelled &&               recognizer.state != .failed &&               isTrackingPanLocation {        let panOffset = recognizer.translationInView(tableView)        // determine offset of the pan from the start here.         // When offset is far enough from table view top edge -         // dismiss your view controller. Additionally you can         // determine if pan goes in the wrong direction and         // then reset flag isTrackingPanLocation to false        let eligiblePanOffset = panOffset.y > 200        if eligiblePanOffset {            recognizer.enabled = false            recognizer.enabled = true            dismissViewControllerAnimated(true, completion: nil)        }        if panOffset.y < 0 {            isTrackingPanLocation = false        }    } else {        isTrackingPanLocation = false    }}public func gestureRecognizer(gestureRecognizer: UIGestureRecognizer,     shouldRecognizeSimultaneouslyWithGestureRecognizer                     otherGestureRecognizer: UIGestureRecognizer) -> Bool {    return true}


Swift 4

var panGestureRecognizer : UIPanGestureRecognizer!override func viewDidLoad() {    mainTableView.bounces = true    panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(self.panRecognized))    panGestureRecognizer.delegate = self    mainTableView.addGestureRecognizer(panGestureRecognizer)}@objc func panRecognized(recognizer: UIPanGestureRecognizer) {    if recognizer.state == .began && mainTableView.contentOffset.y == 0 {    } else if recognizer.state != .ended && recognizer.state != .cancelled && recognizer.state != .failed {        let panOffset = recognizer.translation(in: mainTableView)        let eligiblePanOffset = panOffset.y > 300        if eligiblePanOffset {            recognizer.isEnabled = false            recognizer.isEnabled = true            self.dismiss(animated: true, completion: nil)        }    }}func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {    return true}


Why don't you place print(offsetY) in scrollViewDidScroll. I suspect that (-offsetY) > (tableHeaderHeight+adjustment) will never be satisfied because of the rubber banding will cause the tableview to rebound before it can dismiss the view controller