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

SwiftUI集成Admob:广告关闭时自动关闭父视图求助

SwiftUI集成AdMob:广告关闭时自动关闭父视图解决方案

核心思路

通过在AdCoordinator中添加闭包回调或Combine事件流,将广告关闭的事件传递到SwiftUI视图,触发视图的dismiss()动作。以下是两种实用方案:


方案1:闭包回调(简洁直接)

1. 修改AdCoordinator,添加关闭回调闭包

import GoogleMobileAds

class AdCoordinator: NSObject, GADFullScreenContentDelegate {
    // 定义广告关闭时的回调闭包
    var onAdDismissed: (() -> Void)?

    // AdMob委托方法:广告关闭时触发
    func adDidDismissFullScreenContent(_ ad: GADFullScreenPresentingAd) {
        onAdDismissed?() // 执行闭包,通知视图关闭
    }

    // 其他AdMob委托方法(如加载失败、展示失败等)可按需实现
}

2. 在SomeView中绑定闭包并触发关闭

import SwiftUI
import GoogleMobileAds

struct SomeView: View {
    // 使用SwiftUI 3.0+的环境变量dismiss,替代旧的presentationMode
    @Environment(\.dismiss) private var dismiss
    @State private var adCoordinator = AdCoordinator()

    var body: some View {
        Button("展示广告") {
            loadAndShowInterstitialAd()
        }
        .onAppear {
            // 绑定闭包:广告关闭时调用dismiss
            adCoordinator.onAdDismissed = {
                dismiss()
            }
        }
    }

    // 加载并展示插屏广告的逻辑
    private func loadAndShowInterstitialAd() {
        let interstitialAd = GADInterstitialAd(adUnitID: "你的AdMob广告单元ID")
        interstitialAd.load(GADRequest()) { ad, error in
            guard let ad = ad else { return }
            ad.fullScreenContentDelegate = adCoordinator
            // 获取根视图控制器以展示广告(iOS 13+适配)
            if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
               let rootVC = windowScene.windows.first?.rootViewController {
                ad.present(fromRootViewController: rootVC)
            }
        }
    }
}

方案2:ViewModel+Combine事件流(适合复杂场景)

如果你的页面逻辑较多,可通过ViewModel管理广告状态,用Combine传递关闭事件:

1. 实现带Combine事件的ViewModel

import Combine
import GoogleMobileAds

class AdViewModel: ObservableObject {
    // 广告关闭事件流
    let adDismissed = PassthroughSubject<Void, Never>()
    private let adCoordinator = AdCoordinator()

    init() {
        // 绑定Coordinator的回调到事件流
        adCoordinator.onAdDismissed = { [weak self] in
            self?.adDismissed.send()
        }
    }

    func showInterstitialAd() {
        let interstitialAd = GADInterstitialAd(adUnitID: "你的AdMob广告单元ID")
        interstitialAd.load(GADRequest()) { ad, error in
            guard let ad = ad else { return }
            ad.fullScreenContentDelegate = self.adCoordinator
            if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
               let rootVC = windowScene.windows.first?.rootViewController {
                ad.present(fromRootViewController: rootVC)
            }
        }
    }
}

2. 在SomeView中监听事件流

import SwiftUI
import Combine

struct SomeView: View {
    @Environment(\.dismiss) private var dismiss
    @StateObject private var adViewModel = AdViewModel()

    var body: some View {
        Button("展示广告") {
            adViewModel.showInterstitialAd()
        }
        // 监听广告关闭事件,触发视图关闭
        .onReceive(adViewModel.adDismissed) {
            dismiss()
        }
    }
}

注意事项

  • 闭包中使用[weak self]避免循环引用,防止内存泄漏。
  • 获取根视图控制器的方式适配了iOS 13+的多场景模式,比直接取UIApplication.shared.windows更可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 04:42:41