Show popover with a clear background

Earlier I ran into a problem (again!) to show a popover with clear or translucent background. This popup is essentially a UIViewController subclass which needs to be presented over the source view controller. The viewController might have one or more subviews as its children.

To give you an idea, this modal should look something like this,

expected_popover_image

Here is the code and explanation on how I did it,
(Note: I have changed background from clearColor to transparent black color to give an idea on which part of controller we are actually overlaying on the viewport)

Please make sure to present the view controller after entire view hierarchy is constructed, otherwise it will give you a warning about presenting a view which is not in the current view hierarchy


override func viewDidAppear(_ animated: Bool) {
	super.viewDidAppear(animated)
	if let presentedViewController = self.storyboard?.instantiateViewController(withIdentifier: "myview") {
		presentedViewController.providesPresentationContextTransitionStyle = true
		presentedViewController.definesPresentationContext = true
		presentedViewController.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext;
		presentedViewController.view.backgroundColor = UIColor.init(white: 0.4, alpha: 0.8)
		self.present(presentedViewController, animated: true, completion: nil)
	}
}

Here's the final version with slight additions like label on the overlay view.

final_popup_overlay

As a bonus, here is the tip to dismiss view controller when user taps anywhere outside the view controller. There are two things

  1. Intercept the touch/tap
  2. Check if the view on which tap is made is self.view. If it is, dismiss the modal

override func touchesBegan(_ touches: Set, with event: UIEvent?) {
    if let touch = touches.first {
        if (touch.view == self.view) {
            self.dismiss(animated: true, completion: nil)
        }
    }
}

This code sample is tested on both iOS9 and iOS10 and works well on both. I took the efforts to put this on the blog cause I ran into this issue multiple times and I always spent significant amount of time trying to find the solution. Hope this post helps someone who is trying to achieve the similar thing

If you have any more questions, don't hesitate to reach out to me. You can find my contact information here