Drag to dismiss a UIPresentationController

Published

I have made a UIPresentationController that fits any view controller and shows up on half of the screen using this tutorial. Now I would love to add drag to dismiss to this. I’m trying to have the drag feel natural and responsive like the drag experience for "Top Stories" on the Apple iOS 13 stocks app. I thought the iOS 13 modal drag to dismiss would get carried over but it doesn’t to this controller but it doesn’t.

Every bit of code and tutorial I found had a bad dragging experience. Does anyone know how to do this? I’ve been trying / searching for the past week. Thank you in advance

Here’s my code for the presentation controller

class SlideUpPresentationController: UIPresentationController {
    // MARK: - Variables
    private var dimmingView: UIView!
    
    //MARK: - View functions
    override init(presentedViewController: UIViewController, presenting presentingViewController: UIViewController?) {
        super.init(presentedViewController: presentedViewController, presenting: presentingViewController)
        setupDimmingView()
    }
    
    override func containerViewWillLayoutSubviews() {
      presentedView?.frame = frameOfPresentedViewInContainerView
    }
    
    override var frameOfPresentedViewInContainerView: CGRect {
        guard let container = containerView else { return super.frameOfPresentedViewInContainerView }
        let width = container.bounds.size.width
        let height : CGFloat = 300.0
        
        return CGRect(x: 0, y: container.bounds.size.height - height, width: width, height: height)
    }
    
    override func presentationTransitionWillBegin() {
        guard let dimmingView = dimmingView else { return }
        
        containerView?.insertSubview(dimmingView, at: 0)
      
      NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "V:|[dimmingView]|",
                                                                 options: [],
                                                                 metrics: nil,
                                                                 views: ["dimmingView": dimmingView]))
      
      NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "H:|[dimmingView]|",
                                                                 options: [],
                                                                 metrics: nil,
                                                                 views: ["dimmingView": dimmingView]))
      
      guard let coordinator = presentedViewController.transitionCoordinator else {
        dimmingView.alpha = 1.0
        return
      }
      
      coordinator.animate(alongsideTransition: { _ in
        self.dimmingView.alpha = 1.0
      })
    }
    
    override func dismissalTransitionWillBegin() {
      guard let coordinator = presentedViewController.transitionCoordinator else {
        dimmingView.alpha = 0.0
        return
      }
      
      coordinator.animate(alongsideTransition: { _ in
        self.dimmingView.alpha = 0.0
      })
    }
    
    func setupDimmingView() {
      dimmingView = UIView()
      dimmingView.translatesAutoresizingMaskIntoConstraints = false
      dimmingView.backgroundColor = UIColor(white: 0.0, alpha: 0.5)
      dimmingView.alpha = 0.0
      
      let recognizer = UITapGestureRecognizer(target: self,
                                              action: #selector(handleTap(recognizer:)))
      dimmingView.addGestureRecognizer(recognizer)
    }
    
    @objc func handleTap(recognizer: UITapGestureRecognizer) {
      presentingViewController.dismiss(animated: true)
    }
}

Source: Ios

Published
Categorised as draggable, ios, swift, uipangesturerecognizer, uipresentationcontroller

Answers

Leave a Reply

Your email address will not be published. Required fields are marked *

Still Have Questions?


Our dedicated development team is here for you!

We can help you find answers to your question for as low as 5$.

Contact Us
faq