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

SwiftUI展示AdMob插页广告导致导航流程中断问题求助

解决AdMob插页广告后详情视图自动返回Dashboard的问题

我的应用包含Dashboard视图,用户点击其中项目时应导航至详情视图并全屏展示。但当前存在问题:展示AdMob插页广告后,详情视图(子视图)仅短暂显示,随即自动返回Dashboard视图(父视图)。Dashboard跳转至详情视图的代码为标准实现,以下是我的AdMob管理代码:

class InterstitialAdsManager: NSObject, GADFullScreenContentDelegate, ObservableObject {

    @Published var interstitialAdLoaded: Bool = false

    var interstitialAd: GADInterstitialAd?

    let AD_UNIT_ID = "ca-app-pub-3940256032142544/xxxxxxxxx"

    override init() {
        super.init()
    }

    func loadInterstitialAd() {
    
        GADInterstitialAd.load(withAdUnitID: AD_UNIT_ID, request: GADRequest()) { [weak self] ad, error in
        
            guard let self = self else { return }
        
            if let error = error {
            
                print("🔴: \(error.localizedDescription)")
                self.interstitialAdLoaded = false
            
                return
            
            }
        
            print("🟢: Loading succeeded")
            self.interstitialAdLoaded = true
            self.interstitialAd = ad
            self.interstitialAd?.fullScreenContentDelegate = self
        
        }
    
    }

    func displayInterstitialAd(viewController: UIViewController) {

        let root = UIApplication.shared.windows.last?.rootViewController

        if let ad = interstitialAd {
        
            ad.present(fromRootViewController: root)
            self.interstitialAdLoaded = false
        
        } else {
        
            print("🔵: Ad wasn't ready")
            self.interstitialAdLoaded = false
            self.loadInterstitialAd()
        
        }
    
    }

    func ad(_ ad: GADFullScreenPresentingAd, didFailToPresentFullScreenContentWithError error: Error) {

        print("🟡: Failed to display interstitial ad")
        self.loadInterstitialAd()
    
    }

    func adWillPresentFullScreenContent(_ ad: GADFullScreenPresentingAd) {

        print("🤩: Displayed an interstitial ad")
        self.interstitialAdLoaded = false
    
    }

    func adDidDismissFullScreenContent(_ ad: GADFullScreenPresentingAd) {

        print("😔: Interstitial ad closed")
    
    }

}

问题根源

你在displayInterstitialAd方法里使用全局的UIApplication.shared.windows.last?.rootViewController作为广告的展示根控制器,这会让广告直接覆盖整个应用的根视图栈。当广告关闭后,系统会自动回到根控制器层级,导致刚推入导航栈的详情视图被强制退回。

修复方案

1. 修正广告展示的控制器

把广告展示的根控制器改成传入的viewController参数,这样广告会在当前导航栈的上下文内展示,不会破坏原有视图层级:

func displayInterstitialAd(viewController: UIViewController) {
    if let ad = interstitialAd {
        // 替换全局root为传入的当前控制器
        ad.present(fromRootViewController: viewController)
        self.interstitialAdLoaded = false
    } else {
        print("🔵: Ad wasn't ready")
        self.interstitialAdLoaded = false
        self.loadInterstitialAd()
    }
}

2. 调整广告与导航的时序

避免同时触发导航和广告展示,二选一拆分流程:

  • 先展示广告,再进详情:在adDidDismissFullScreenContent回调中执行导航到详情视图的逻辑
  • 先进详情,再展示广告:在详情视图的viewDidAppear方法里调用广告展示方法,确保视图已经完成入栈

3. 补充广告关闭后的加载逻辑

在广告关闭后重新加载下一个广告,保证后续展示可用:

func adDidDismissFullScreenContent(_ ad: GADFullScreenPresentingAd) {
    print("😔: Interstitial ad closed")
    // 重新加载广告,为下一次展示做准备
    self.loadInterstitialAd()
}

额外注意事项

  • 不要在导航跳转的同步流程里触发广告展示,必须拆分为异步操作(等待广告关闭再导航,或导航完成后再弹广告)
  • 确保interstitialAdLoaded的状态更新准确,避免重复触发广告展示

内容的提问来源于stack exchange,提问作者Learn2Code

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 16:03:28