如何使用Swift实现无背景阴影的ViewController模态表单展示
无背景阴影模态表单实现方案
你要的效果不需要强制自定义UIPresentationController,iOS 15及以上版本可以直接用系统原生API快速实现,仅兼容iOS 14及更低版本时才需要自定义。
方案1:iOS 15+ 极简实现
直接用系统自带的UISheetPresentationController修改配置即可,核心是关闭背景蒙层:
let targetVC = YourModalViewController() targetVC.modalPresentationStyle = .pageSheet if let sheetController = targetVC.sheetPresentationController { // 核心配置:指定最大尺寸下不添加背景蒙层阴影 sheetController.largestUndimmedDetentIdentifier = .large // 可按需配置 sheet 高度,比如半高、全高 sheetController.detents = [.medium(), .large()] // 按需配置其他属性,比如滑动提示条、圆角等 sheetController.prefersGrabberVisible = true } present(targetVC, animated: true)
只需要设置largestUndimmedDetentIdentifier为你用到的最大尺寸标识,系统就会自动取消对应状态下的背景阴影,完全不需要额外自定义逻辑。
方案2:兼容iOS 14及更低版本,自定义UIPresentationController
如果需要支持旧系统,就需要自定义 presentation 控制器移除默认蒙层:
- 自定义无阴影的PresentationController
class NoShadowSheetPresentationController: UIPresentationController { override func presentationTransitionWillBegin() { super.presentationTransitionWillBegin() // 容器背景设为透明,移除默认阴影蒙层 containerView?.backgroundColor = .clear } // 保留底层控制器的视图不被移除 override var shouldRemovePresentersView: Bool { false } }
- 实现转场代理返回自定义控制器
class CustomSheetTransitionDelegate: NSObject, UIViewControllerTransitioningDelegate { func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? { NoShadowSheetPresentationController(presentedViewController: presented, presenting: presenting) } }
- 调用时配置转场代理
let targetVC = YourModalViewController() // 注意转场代理需要持有,避免被释放 private let transitionDelegate = CustomSheetTransitionDelegate() targetVC.transitioningDelegate = transitionDelegate targetVC.modalPresentationStyle = .custom present(targetVC, animated: true)
使用自定义方案时,你需要自行实现sheet的高度、圆角、滑动交互等系统默认提供的sheet效果。
内容的提问来源于stack exchange,提问作者Kevin Issac
相关产品推荐
相关产品推荐

