How can I implement “drag right to dismiss” a View Controller that's in a navigation stack?

后端 未结 6 1859
忘了有多久
忘了有多久 2020-12-07 18:24

By default, if you drag right from the left edge of the screen, it will drag away the ViewController and take it off the stack.

I want to extend this functionality t

6条回答
  •  南笙
    南笙 (楼主)
    2020-12-07 18:48

    Swift 4 version of the accepted answer by @Warif Akhand Rishi

    Even though this answer does work there are 2 quirks that I found out about it.

    1. if you swipe left it also dismisses just as if you were swiping right.
    2. it's also very delicate because if even a slight swipe is directed in either direction it will dismiss the vc.

    Other then that it definitely works and you can swipe either right or left to dismiss.

    class ViewController: UIGestureRecognizerDelegate, UINavigationControllerDelegate {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            navigationController?.interactivePopGestureRecognizer?.delegate = self
            let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture(_:)))
            view.addGestureRecognizer(panGesture)
        }
    
        @objc func handlePanGesture(_ gesture: UIPanGestureRecognizer){
    
            let interactiveTransition = UIPercentDrivenInteractiveTransition()
    
            let percent = max(gesture.translation(in: view).x, 0) / view.frame.width
    
            switch gesture.state {
    
            case .began:
                navigationController?.delegate = self
    
                // *** use this if the vc is PUSHED on the stack **
                navigationController?.popViewController(animated: true)
    
                // *** use this if the vc is PRESENTED **
                //navigationController?.dismiss(animated: true, completion: nil)
    
            case .changed:
                interactiveTransition.update(percent)
    
            case .ended:
                let velocity = gesture.velocity(in: view).x
    
                // Continue if drag more than 50% of screen width or velocity is higher than 1000
                if percent > 0.5 || velocity > 1000 {
                    interactiveTransition.finish()
                } else {
                    interactiveTransition.cancel()
                }
    
            case .cancelled, .failed:
                interactiveTransition.cancel()
    
            default:break
            }
        }
    }
    

提交回复
热议问题