iOS modalPresentationStyle透明背景下presenting VC的viewWillAppear不触发问题求解
解决方案
方案1:自定义UIPresentationController(推荐,原生无侵入)
系统默认的.fullScreen模态无法实现透明背景的核心原因是:默认的UIPresentationController会在弹出完成后将presenting控制器(VC1)的视图从视图层级中移除,你只需要通过自定义PresentationController修改这个行为即可同时满足「透明背景」和「保留生命周期回调」两个需求。
具体实现步骤:
- 继承UIPresentationController,重写
shouldRemovePresentersView属性返回false,阻止系统移除下层VC1的视图:
class TransparentFullScreenPresentationController: UIPresentationController { override var shouldRemovePresentersView: Bool { false } }
- 在你的Coordinator中实现
UIViewControllerTransitioningDelegate协议,返回上述自定义的PresentationController:
extension YourCoordinator: UIViewControllerTransitioningDelegate { func presentationController( forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController ) -> UIPresentationController? { TransparentFullScreenPresentationController( presentedViewController: presented, presenting: presenting ) } }
- 弹出VC2时按如下配置即可:
let vc2 = VC2() vc2.view.backgroundColor = .clear // 按需设置透明/半透明背景 vc2.modalPresentationStyle = .fullScreen vc2.transitioningDelegate = 你的Coordinator实例 vc1.present(vc2, animated: true)
该方案的优势:
- 全部使用系统公开API,无任何Hack,兼容所有支持UIKit的iOS版本
- 完全保留
.fullScreen模态的生命周期逻辑,VC2 dismiss后VC1的viewWillAppear、viewDidAppear等回调会正常触发 - 所有转场逻辑都封装在Coordinator层,不需要侵入VC1、VC2的内部代码,也不需要额外的通知、代理回调,完全匹配你当前的架构设计
方案2:轻量兼容方案(仅需调整dismiss逻辑)
如果不想自定义转场,且你所有的VC2 dismiss逻辑都由Coordinator管控,可以在调用dismiss方法的completion闭包中手动触发VC1的生命周期相关逻辑:
vc2.dismiss(animated: true) { [weak vc1] in vc1?.viewWillAppear(true) // 其他需要执行的逻辑 }
该方案实现成本极低,但仅适用于所有dismiss操作都由Coordinator统一管控的场景,不支持用户手势下滑dismiss的情况。
内容的提问来源于stack exchange,提问作者CloudBalancing
相关产品推荐
相关产品推荐

