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