I am presenting a modal view controller as a form sheet and dismissing it when the cancel button, which is a bar button item, is clicked. I need to dismiss it when I tap on
Based on Bart van Kuik's answer and NavAutoDismiss and other great snippets here.
class DismissableNavigationController: UINavigationController, UIGestureRecognizerDelegate {
private var tapOutsideRecognizer: UITapGestureRecognizer!
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
if tapOutsideRecognizer == nil {
tapOutsideRecognizer = UITapGestureRecognizer(target: self, action: #selector(DismissableNavigationController.handleTapBehind))
tapOutsideRecognizer.numberOfTapsRequired = 1
tapOutsideRecognizer.cancelsTouchesInView = false
tapOutsideRecognizer.delegate = self
view.window?.addGestureRecognizer(tapOutsideRecognizer)
}
}
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
if tapOutsideRecognizer != nil {
view.window?.removeGestureRecognizer(tapOutsideRecognizer)
tapOutsideRecognizer = nil
}
}
func close(sender: AnyObject) {
dismissViewControllerAnimated(true, completion: nil)
}
func handleTapBehind(sender: UITapGestureRecognizer) {
if sender.state == UIGestureRecognizerState.Ended {
var location: CGPoint = sender.locationInView(nil)
if UIInterfaceOrientationIsLandscape(UIApplication.sharedApplication().statusBarOrientation) {
location = CGPoint(x: location.y, y: location.x)
}
if !view.pointInside(view.convertPoint(location, fromView: view.window), withEvent: nil) {
view.window?.removeGestureRecognizer(sender)
close(sender)
}
}
}
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
}
let vc = MyViewController()
let nc = DismissableNavigationController(rootViewController: vc)
nc.modalPresentationStyle = UIModalPresentationStyle.FormSheet
presentViewController(nc, animated: true, completion: nil)