I want to pull down to dismiss UITableViewController
so I used scrollViewDidScroll
method but it didn't works!
class CommentViewController: PFQueryTableViewController {
private let tableHeaderHeight: CGFloat = 350.0
extension CommentViewController
{
override func scrollViewDidScroll(scrollView: UIScrollView)
{
// Pull down to dismiss TVC
let offsetY = scrollView.contentOffset.y
let adjustment: CGFloat = 130.0
// for later use
if (-offsetY) > (tableHeaderHeight+adjustment) {
self.dismissViewControllerAnimated(true, completion: nil)
}
}
}
For people looking at this in 2019 -- A more modern approach would use the UIGestureRecognizerDelegate methods, instead of keeping extra state in your view controller. For example:
private weak var panFromTop: UIPanGestureRecognizer?
override func viewDidLoad() {
super.viewDidLoad()
// Add pan gesture recognizer
let panFromTop = UIPanGestureRecognizer(target: self, action: #selector(handlePanFromTop(_:)))
panFromTop.delegate = self
tableView.addGestureRecognizer(panFromTop)
self.panFromTop = panFromTop
}
@objc func handlePanFromTop(_ recognizer: UIPanGestureRecognizer) {
switch recognizer.state {
case .began:
// TODO: BEGIN YOUR ANIMATION HERE
case .changed:
// TODO: UPDATE YOUR ANIMATION HERE
default:
let translation = recognizer.translation(in: view)
let velocity = recognizer.velocity(in: view)
if ((translation.y + velocity.y) / view.bounds.height) > 0.5 {
// TODO: FINISH YOUR ANIMATION HERE
} else {
// TODO: CANCEL YOUR ANIMATION HERE
}
}
}
Disable bounce at the top of the table view only:
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.contentOffset.y < 0 {
scrollView.setContentOffset(.zero, animated: false)
}
}
Then implement the gesture recognizer delegate methods:
func gestureRecognizer(
_ gestureRecognizer: UIGestureRecognizer,
shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer
) -> Bool {
return true
}
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
guard let recognizer = gestureRecognizer as? UIPanGestureRecognizer,
recognizer === panFromTop else {
// Only require special conditions for the panFromTop gesture recognizer
return true
}
// Require the scroll view to be at the top,
// and require the pan to start by dragging downward
return (
tableView.contentOffset.y <= 0 &&
recognizer.velocity(in: view).y > 0
)
}
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 = false
var 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
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With