如何在UISheetPresentationController中移除背景暗化并保留点击关闭功能?
如何移除UISheetPresentationController背景暗化并保留点击关闭功能
我使用UISheetPresentationController展示视图,代码如下:
@IBAction func click(_ sender: Any) { let whiteViewController = WhiteViewController.instanceFromMainStoryBoard() if let sheet = whiteViewController.sheetPresentationController { sheet.detents = [.medium()] sheet.prefersScrollingExpandsWhenScrolledToEdge = false sheet.prefersGrabberVisible = false // Remove dim effect. ////sheet.largestUndimmedDetentIdentifier = .medium } self.present(whiteViewController, animated: true) }
当前实现的特性:
- 背景暗化
- 点击任意位置可关闭视图

但我需要移除背景暗化,同时保留点击关闭功能。当添加sheet.largestUndimmedDetentIdentifier = .medium后,背景暗化消失,但点击关闭功能也失效了:
请问有没有办法同时实现这两个需求?
解决方案
方法1:自定义透明背景+点击手势
通过给Sheet添加全屏透明背景视图,手动实现点击关闭逻辑,同时用largestUndimmedDetentIdentifier移除系统暗化:
@IBAction func click(_ sender: Any) { let whiteViewController = WhiteViewController.instanceFromMainStoryBoard() if let sheet = whiteViewController.sheetPresentationController { sheet.detents = [.medium()] sheet.prefersScrollingExpandsWhenScrolledToEdge = false sheet.prefersGrabberVisible = false // 移除系统背景暗化 sheet.largestUndimmedDetentIdentifier = .medium // 添加全屏透明点击背景 let tapBackground = UIView(frame: UIScreen.main.bounds) tapBackground.backgroundColor = .clear // 把背景放在Sheet内容下方 whiteViewController.view.insertSubview(tapBackground, at: 0) // 添加点击手势关闭Sheet let tapGesture = UITapGestureRecognizer(target: self, action: #selector(dismissPresentedSheet)) tapBackground.addGestureRecognizer(tapGesture) } self.present(whiteViewController, animated: true) } @objc private func dismissPresentedSheet() { dismiss(animated: true) }
方法2:修改系统暗化视图透明度
保留系统默认的点击关闭逻辑,在Sheet展示后找到系统的暗化背景视图,将其设为透明:
@IBAction func click(_ sender: Any) { let whiteViewController = WhiteViewController.instanceFromMainStoryBoard() if let sheet = whiteViewController.sheetPresentationController { sheet.detents = [.medium()] sheet.prefersScrollingExpandsWhenScrolledToEdge = false sheet.prefersGrabberVisible = false self.present(whiteViewController, animated: true) { [weak self] in // 递归查找系统暗化背景视图 func findDimView(in view: UIView) -> UIView? { let alpha = view.backgroundColor?.cgColor.alpha ?? 0 if alpha > 0 && alpha < 1 { return view } for subview in view.subviews { if let dimView = findDimView(in: subview) { return dimView } } return nil } guard let window = self?.view.window, let dimView = findDimView(in: window) else { return } dimView.backgroundColor = .clear } } }
注意点
- 方法2依赖系统视图层级,苹果后续更新可能导致失效,稳定性不如方法1
- 方法1需确保透明背景视图覆盖全屏,避免出现点击无响应的区域
内容的提问来源于stack exchange,提问作者Cheok Yan Cheng
相关产品推荐
相关产品推荐

