4

I don't know how exactly to achieve the following in Swift:

I am displaying a modal form sheet popup in my iPad app. In order to dismiss this view I have added a button that dismisses it. But what I really want is for it to dismiss when you click outside of the view. Almost the same behaviour as the popover. I have tried achieving this by adding tap gestures, making it a popover, any of the presentation styles, nothing works.

Has someone maybe done this so that you can point me in the right direction?

rmaddy
  • 314,917
  • 42
  • 532
  • 579
user2980509
  • 132
  • 1
  • 3
  • 12

1 Answers1

12

I had to display some screens like a popup in my app, so I've made a base class that looks like this:

class MyBasePopUp: UIViewController, UIGestureRecognizerDelegate {

var tap: UITapGestureRecognizer!
override func viewDidAppear(_ animated: Bool) {
    
    tap = UITapGestureRecognizer(target: self, action: #selector(onTap(sender:)))
    tap.numberOfTapsRequired = 1
    tap.numberOfTouchesRequired = 1
    tap.cancelsTouchesInView = false
    tap.delegate = self
    self.view.window?.addGestureRecognizer(tap)
}

internal func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}

internal func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
    let location = touch.location(in: self.view)
    
    if self.view.point(inside: location, with: nil) {
        return false
    }
    else {
        return true
    }
}

@objc private func onTap(sender: UITapGestureRecognizer) {
    
    self.view.window?.removeGestureRecognizer(sender)
    self.dismiss(animated: true, completion: nil)
}

This is just to dismiss the popup, be careful if you have multiple gestures.

Shurtugal
  • 254
  • 2
  • 8
  • This mostly did what I need. Maybe I'm using it slightly differently, but I had to use `presentedViewController.view` instead of `self.view` before it would correctly recognize taps, and I had to remove the first line of `onTap` or else it would only work once. – John Montgomery Apr 02 '18 at 20:47
  • 1
    if the popup is not destroyed, it will add another gesture rec. when user opens the popup, that's why i needed self.view.window?.removeGestureRecognizer(sender) – Shurtugal Jun 13 '18 at 08:44
  • In `let location = touch.location(in: self.view)` I had to change `self.view` to use my particular view, but after that, things worked as intended. – David A Sep 05 '18 at 20:56