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
相关产品推荐
相关产品推荐

