2

Similar question to : Disable gesture to pull down form/page sheet modal presentation

Looking for functionality exactly like this, except with a tableview under the navigation controller:

enter image description here

when I attempt to use the answer given, touchesBegan and touchesEnded do not get called, so I tried calling the functions in scrollViewWillBeginDragging and scrollViewWillEndDragging and while it does get called, it doesnt solve the issue. Scrolling the tableview will still close the modal most of the time.

I do not want to present over full screen.
isModalInPresentation stops it from closing but the bounce down still attempts. I want to stop that altogether.

I want to be able to only close if the user presses cancel or actually grabs the navigation bar to close like in the gif, and swipes within the tableview to only scroll the tableview. What else can I try?

1 Answers1

0

If I understand well, this is an example to do it programmatically... Declare button under your controller class:

let myButton: UIButton = {
    let b = UIButton()
    b.backgroundColor = .black
    b.setTitle("Tap me!", for: .normal)
    b.setTitleColor(.white, for: .normal)
    b.titleLabel?.font = .systemFont(ofSize: 17, weight: .regular)
    b.layer.cornerRadius = 12
    b.clipsToBounds = true
    b.translatesAutoresizingMaskIntoConstraints = false

    return b
}()

Now in viewDidLoad add target and set constraints:

override func viewDidLoad() {
    super.viewDidLoad()
    
    view.backgroundColor = .white
    
    myButton.addTarget(self, action: #selector(callSeetController), for: .touchUpInside)
    
    view.addSubview(myButton)
    myButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    myButton.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    myButton.heightAnchor.constraint(equalToConstant: 50).isActive = true
    myButton.widthAnchor.constraint(equalToConstant: 200).isActive = true
}

After that call the func to present an set sheet attributes:

@objc fileprivate func callSeetController() {
    let detailViewController = SecondController()
                    
    let nav = UINavigationController(rootViewController: detailViewController)
    nav.isModalInPresentation = true // disable swipe down
    
    if let sheet = nav.sheetPresentationController {
        sheet.detents = [.large()]

    }
    
    let image = UIImage(systemName: "x.circle")

    let dismiss = UIBarButtonItem(image: image, primaryAction: .init(handler: { [weak self] _ in
        if let sheet = nav.sheetPresentationController {
            sheet.animateChanges {
                self?.dismiss(animated: true, completion: nil)
            }
        }
    }))
    
    detailViewController.navigationItem.rightBarButtonItem = dismiss
    detailViewController.navigationController?.navigationBar.tintColor = .white

    present(nav, animated: true, completion: nil)
}

The result:

enter image description here

Fabio
  • 5,432
  • 4
  • 22
  • 24
  • 1
    This does the same thing as `isModalInPresentation = true` . Ive gotten that far, but I'd like to prevent the partial pull down entirely unless the user grabs the navigation bar at the top of the page sheet. I do not want swipes within the tableview to pull down the modal at all. – thesuffering Apr 09 '22 at 17:04