Steps:
- Add the view controller that you want to be able to dismiss.
- From the calling view controller, add an action to present it modally.
- On the segue, change
Presentation
value toOver Current Context
. - See code below.
class ViewController: UIViewController { | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
let recognizer = UIPanGestureRecognizer(target: self, action: #selector(pan(_:))) | |
self.view.addGestureRecognizer(recognizer) | |
} | |
func pan(_ recognizer: UIPanGestureRecognizer) { | |
let translation = recognizer.translation(in: view) | |
view.frame.origin.y = translation.y | |
if recognizer.state == .ended { | |
let velocity = recognizer.velocity(in: view) | |
if velocity.y >= 800 || translation.y >= view.frame.height / 3 * 2 { | |
dismiss(animated: true, completion: nil) | |
} else { | |
restoreView() | |
} | |
} else if recognizer.state == .cancelled { | |
restoreView() | |
} | |
} | |
func restoreView() { | |
UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseOut, animations: { | |
self.view.frame.origin = CGPoint(x: 0, y: 0) | |
}, completion: nil) | |
} | |
} |