I\'m using UIPopoverPresentationController
to present popovers in an iOS app. I want to dim the background behind the popover when it comes up. How can I do thi
A drop-in non-intrusive solution: showing/hiding up an overlay view via UIPopoverPresentationControllerDelegate
, like this: (in Swift 2.0)
class PopoverDelegate: NSObject, UIPopoverPresentationControllerDelegate {
var overlay: UIView?
dynamic func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
return .None
}
dynamic func presentationController(presentationController: UIPresentationController, willPresentWithAdaptiveStyle style: UIModalPresentationStyle, transitionCoordinator: UIViewControllerTransitionCoordinator?) {
// add a semi-transparent view to parent view when presenting the popover
let parentView = presentationController.presentingViewController.view
let overlay = UIView(frame: parentView.bounds)
overlay.backgroundColor = UIColor(white: 0.0, alpha: 0.4)
parentView.addSubview(overlay)
let views: [String: UIView] = ["parentView": parentView, "overlay": overlay]
parentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[overlay]|", options: [], metrics: nil, views: views))
parentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[overlay]|", options: [], metrics: nil, views: views))
overlay.alpha = 0.0
transitionCoordinator?.animateAlongsideTransition({ _ in
overlay.alpha = 1.0
}, completion: nil)
self.overlay = overlay
}
deinit {
// remove the overlay with animation.
// the delegate method popoverPresentationControllerDidDismissPopover(_:) is not called
// if the popover is dismissed programmatically,
// so the removal goes here.
guard let overlay = overlay else {
return
}
dispatch_async(dispatch_get_main_queue()) {
UIView.animateWithDuration(0.2, animations: {
overlay.alpha = 0.0
}, completion: { _ in
overlay.removeFromSuperview()
})
}
}
}
Then when a popver is about to be presented, set the delegate of UIPopoverPresentationController
to an instance of PopoverDelegate
, and you get a dimmed background behind the popover.