iOS17中Popover设置modalPresentationStyle后背景无法透明
iOS 17 Popover 背景无法透明问题解决
问题描述
在iOS 15和iOS 16版本中,popover弹窗的背景可以正常设置为透明,但升级到iOS 17后,即使将弹窗内ViewController的view.backgroundColor设为.clear,背景仍然无法透明,出现默认的不透明背景。
环境信息
- Xcode版本:15.0 (15A240d)
- iOS版本:17.0
- macOS版本:Sonoma 14.0
解决方案
iOS 17对Popover的默认样式做了调整,默认启用了系统内容外观,导致自定义透明背景失效,通过以下步骤修复:
1. 禁用Popover默认内容外观
在创建并配置MessagePopMenuViewController实例时,添加代码明确禁用系统默认内容外观,并设置弹窗view的背景色为透明:
// 在present(popMenuVC, animated: true)之前添加 popMenuVC.view.backgroundColor = .clear popMenuVC.popoverPresentationController?.wantsDefaultContentAppearance = false
2. 确保弹窗ViewController内部背景全透明
在MessagePopMenuViewController的viewDidLoad方法开头,明确设置自身view的背景色为透明:
override func viewDidLoad() { super.viewDidLoad() // 新增:设置view背景透明 view.backgroundColor = .clear reactionButtons.forEach({ $0.backgroundColor = .clear }) topReactionStackView.backgroundColor = .clear bottomReactionStackView.backgroundColor = .clear // 原有逻辑代码... }
3. 适配iOS 17的阴影视图处理(可选)
原代码中遍历子视图隐藏_UICutoutShadowView的方式在iOS 17可能失效,若仍存在阴影问题,可通过popoverPresentationController属性控制:
// 在配置popoverPresentationController时添加 popMenuVC.popoverPresentationController?.shouldRemovePresentersView = false
修改后的关键代码示例
弹窗创建处修改(以第一个分支为例)
let storyboard = UIStoryboard(name: MessagePopMenuViewController.storyboardName, bundle: nil) let popMenuVC = storyboard.instantiateViewController(identifier: MessagePopMenuViewController.storybaordId) { coder in return MessagePopMenuViewController(coder: coder, isLoginUser: isLoginUser, isUpper: isUpper, type: type) } popMenuVC.delegate = self popMenuVC.modalPresentationStyle = .popover // 新增透明背景配置 popMenuVC.view.backgroundColor = .clear popMenuVC.popoverPresentationController?.wantsDefaultContentAppearance = false // 原有配置代码 popMenuVC.popoverPresentationController?.sourceView = currentCell popMenuVC.popoverPresentationController?.sourceRect = sourceRect popMenuVC.popoverPresentationController?.permittedArrowDirections = sourceRect.width > 50 ? (isUpper ? .up : .down) : .unknown popMenuVC.popoverPresentationController?.popoverBackgroundViewClass = MessagePopoverBackgroundView.self popMenuVC.popoverPresentationController?.delegate = self present(popMenuVC, animated: true)
内容的提问来源于stack exchange,提问作者ADAM _YONEDA
相关产品推荐
相关产品推荐

