如何为popover样式的AskController添加背景模糊变暗及旋转适配?
实现Popover背景模糊变暗的简便方案
核心思路
通过给弹出Popover的控制器(presentingViewController)添加全屏模糊+半透明遮罩,并监听AskController的dismiss事件自动移除遮罩;同时利用自动适配属性保证设备旋转后遮罩始终全屏覆盖。
具体实现步骤
1. 封装遮罩工具(UIViewController扩展)
创建通用扩展,方便在任意控制器中快速添加/移除遮罩:
import UIKit extension UIViewController { /// 添加全屏模糊+半黑遮罩,返回遮罩视图用于后续移除 func addPopoverBackgroundMask() -> UIView { let maskView = UIView(frame: view.bounds) // 半透明黑色层增强暗化效果 maskView.backgroundColor = UIColor.black.withAlphaComponent(0.5) // 添加系统模糊效果(可按需更换style:.light/.dark/.extraLight) let blurEffect = UIBlurEffect(style: .dark) let blurView = UIVisualEffectView(effect: blurEffect) blurView.frame = maskView.bounds maskView.addSubview(blurView) // 设置自动适配屏幕旋转 maskView.autoresizingMask = [.flexibleWidth, .flexibleHeight] view.addSubview(maskView) view.sendSubviewToBack(maskView) // 确保遮罩在Popover下方 return maskView } /// 移除指定遮罩视图 func removePopoverBackgroundMask(_ maskView: UIView?) { maskView?.removeFromSuperview() } }
2. 展示AskController时添加遮罩并监听dismiss
在需要弹出AskController的控制器中,调用上述方法添加遮罩,并通过闭包监听dismiss事件自动移除:
let windowAsking = AskController() windowAsking.modalPresentationStyle = .popover // 添加背景遮罩 let maskView = addPopoverBackgroundMask() // 配置Popover参数 if let popoverController = windowAsking.popoverPresentationController { popoverController.sourceView = self.view popoverController.sourceRect = centerOfTheScreen() popoverController.permittedArrowDirections = [] popoverController.delegate = windowAsking } // 监听AskController的dismiss事件,自动移除遮罩 windowAsking.onDismiss = { [weak self] in self?.removePopoverBackgroundMask(maskView) } present(windowAsking, animated: true)
3. 在AskController中添加dismiss回调闭包
给AskController增加一个闭包属性,在dismiss时触发回调:
class AskController: UIViewController, UIPopoverPresentationControllerDelegate, UIPopoverControllerDelegate { // 用于通知外部控制器已dismiss var onDismiss: (() -> Void)? override func viewDidDisappear(_ animated: Bool) { super.viewDidDisappear(animated) // 仅在主动dismiss时触发回调 if isBeingDismissed { onDismiss?() } } // 保留你原有的其他代理实现代码... }
关键说明
- 为什么
popoverPresentationController.backgroundColor无效?该属性仅用于设置Popover内容区域的背景色,无法影响Popover外部的屏幕区域,因此无法实现背景模糊暗化效果。 - 旋转适配:通过设置
autoresizingMask = [.flexibleWidth, .flexibleHeight],遮罩会在设备旋转时自动调整尺寸,始终覆盖全屏。 - 复用性:通过UIViewController扩展,可在任意控制器中快速复用该遮罩逻辑,无需重复编写代码。
内容的提问来源于stack exchange,提问作者Afinainflowers
相关产品推荐
相关产品推荐

