Swift中如何在模态弹出的部分视图控制器下方添加全屏阴影层
可行实现方案
核心逻辑
你需要把阴影层插入到当前模态视图控制器view的最底层,放在子控制器SlidingViewController的view下方,同时把阴影层的frame设置为和当前模态视图控制器的view.bounds完全一致,即可覆盖整个模态控制器的所有区域(包括导航栏),也不会盖住上层的SlidingViewController。
具体实现步骤
- 先定义阴影层全局属性,方便后续移除
private var shadowView: UIView?
- 修改你的
presentInfoVC方法,插入阴影层
func presentInfoVC() { // 先移除旧的阴影层和子控制器 shadowView?.removeFromSuperview() vc.remove() // 初始化阴影层 let shadow = UIView() shadow.backgroundColor = .black.withAlphaComponent(0.5) // 调整透明度控制阴影深浅 shadow.frame = self.view.bounds shadow.autoresizingMask = [.flexibleWidth, .flexibleHeight] // 适配横竖屏切换 self.view.addSubview(shadow) self.shadowView = shadow // 原有子控制器初始化逻辑 vc = SlidingViewController() vc.view.layer.cornerRadius = 10.0 // 如果只需要顶部圆角可加下面这行 // vc.view.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] // 修正原有frame写法问题,直接定位到屏幕底部 vc.view.frame = CGRect(x: 0, y: self.view.bounds.height - 1000, width: self.view.bounds.width, height: 1000) // 把SlidingViewController的view加到阴影层上方,避免被阴影覆盖 self.addChild(vc) self.view.insertSubview(vc.view, aboveSubview: shadow) vc.didMove(toParent: self) // 补全子控制器生命周期回调,避免异常 vc.maximize(completion: nil) }
- 可选扩展:点击阴影层关闭弹窗
如果需要实现点击阴影收起SlidingViewController的效果,给阴影层添加点击手势即可:
// 初始化shadow时添加手势 let tapGesture = UITapGestureRecognizer(target: self, action: #selector(dismissSlidingVC)) shadow.addGestureRecognizer(tapGesture) // 实现关闭方法 @objc private func dismissSlidingVC() { vc.minimize { [weak self] in self?.vc.remove() self?.shadowView?.removeFromSuperview() self?.shadowView = nil } }
原有方案的问题说明
- 给模态视图加阴影覆盖不到导航栏:是因为你之前大概率把阴影层加到了导航栏视图的下方,直接插入到
self.view的最底层就可以覆盖整个模态控制器的所有区域 - 给key window加阴影会全屏遮盖:是因为window层级的视图会盖住当前所有控制器视图,不适合当前场景
内容的提问来源于stack exchange,提问作者aFella
相关产品推荐
相关产品推荐

