You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS modalPresentationStyle透明背景下presenting VC的viewWillAppear不触发问题求解

解决方案

方案1:自定义UIPresentationController(推荐,原生无侵入)

系统默认的.fullScreen模态无法实现透明背景的核心原因是:默认的UIPresentationController会在弹出完成后将presenting控制器(VC1)的视图从视图层级中移除,你只需要通过自定义PresentationController修改这个行为即可同时满足「透明背景」和「保留生命周期回调」两个需求。
具体实现步骤:

  1. 继承UIPresentationController,重写shouldRemovePresentersView属性返回false,阻止系统移除下层VC1的视图:
class TransparentFullScreenPresentationController: UIPresentationController {
    override var shouldRemovePresentersView: Bool {
        false
    }
}
  1. 在你的Coordinator中实现UIViewControllerTransitioningDelegate协议,返回上述自定义的PresentationController:
extension YourCoordinator: UIViewControllerTransitioningDelegate {
    func presentationController(
        forPresented presented: UIViewController,
        presenting: UIViewController?,
        source: UIViewController
    ) -> UIPresentationController? {
        TransparentFullScreenPresentationController(
            presentedViewController: presented,
            presenting: presenting
        )
    }
}
  1. 弹出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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 10:06:04