Вы можете использовать UIPresentationController и UIViewControllerTransitioningDelegate.
В качестве отправной точки здесь приведены несколько строк кода:
UIViewControllerTransitioningDelegate
class OverlayTransitioningDelegate: NSObject, UIViewControllerTransitioningDelegate {
func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
return OverlayPresentationController(presentedViewController:presented, presenting:presenting)
}
}
UIPresentationController
class OverlayPresentationController: UIPresentationController {
private let dimmedBackgroundView = UIView()
private let height: CGFloat = 200.0
override init(presentedViewController: UIViewController, presenting presentingViewController: UIViewController?) {
super.init(presentedViewController: presentedViewController, presenting: presentingViewController)
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(backgroundTapped))
self.dimmedBackgroundView.addGestureRecognizer(tapGestureRecognizer)
}
override var frameOfPresentedViewInContainerView: CGRect {
var frame = CGRect.zero
if let containerBounds = containerView?.bounds {
frame = CGRect(x: 0,
y: containerBounds.height - height,
width: containerBounds.width,
height: height)
}
return frame
}
override func presentationTransitionWillBegin() {
if let containerView = self.containerView, let coordinator = presentingViewController.transitionCoordinator {
containerView.addSubview(self.dimmedBackgroundView)
self.dimmedBackgroundView.backgroundColor = .black
self.dimmedBackgroundView.frame = containerView.bounds
self.dimmedBackgroundView.alpha = 0
coordinator.animate(alongsideTransition: { _ in
self.dimmedBackgroundView.alpha = 0.5
}, completion: nil)
}
}
override func dismissalTransitionDidEnd(_ completed: Bool) {
self.dimmedBackgroundView.removeFromSuperview()
}
@objc private func backgroundTapped() {
self.presentedViewController.dismiss(animated: true, completion: nil)
}
}
Как это назвать
let overlayTransitioningDelegate = OverlayTransitioningDelegate()
@IBAction func onOpenModalOverlay(_ sender: Any) {
let overlayVC = OverlayViewController()
overlayVC.transitioningDelegate = self.overlayTransitioningDelegate
overlayVC.modalPresentationStyle = .custom
self.present(overlayVC, animated: true, completion: nil)
}
Демо
OverlayViewController - это обычный ViewController. Здесь я использовал уродливый зеленый цвет фона, чтобы было легче распознать наложение.