iosswiftuitableviewpresentmodalviewcontroller

ios13 prevent pulling down on tableView which is scrolled to top from dismissing sheet style modally presented viewController


I have a tableViewController which is presented modally with the default sheet style presentation.

I want to keep this modal style as it looks good and works well in my app. And I like the dismiss when pulling down on the navigation bar. However what I don't want is pulling down on the tableView cells to cause the tableViewController to be dismissed when the tableView is already scrolled to the top.

Is there anyway to inhibit this behaviors but keep the sheet style modal presentation? I want the pull down on the tableView to keep the vertical bounce effect and only to be able to dismiss the modally presented tableViewController through pan by pulling down on the navigation bar portion.


Solution

  • You can disable the pull-to-dismiss behavior by setting isModalInPresentation to true on your table view controller when the user begins dragging on the table view, and then reset it back to false when they stop dragging, like so:

    class YourTableViewController: UITableViewController {
        override func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
            isModalInPresentation = true
        }
    
        override func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
            isModalInPresentation = false
        }
    }
    

    Note that you'll still be able to slightly pull down your table view controller, but at least you won't be able to dismiss it entirely. And since the value is set back to false when dragging stops, you'll be able to dismiss by pulling down on the navigation bar.

    Also, if you add a UIRefreshControl to your table view, it disables the pull-to-dismiss behavior when pulling down on the table view.