SwiftUI中展示AdMob插屏广告导致NavigationLink失效问题排查
环境信息
- SwiftUI 5.0
- iOS 17.0
- Xcode 15
预期流程
HOME >> 展示插屏广告 >> CONTENT >> SETTINGS
实际异常
展示广告后导航链完全断裂:
- 进入Content View后,「To Settings」链接无响应
- 返回Home View后,原本的「To Content」链接也失效
- 仅系统自带的返回按钮可正常使用
复现步骤
- 安装GoogleMobileAds库并配置plist相关字段
- 等待广告加载完成后,点击Home View的「To Content」链接
- 展示并关闭测试广告,进入Content View
- 点击「To Settings」无响应;返回Home View后,「To Content」同样失效
App代码
import SwiftUI import GoogleMobileAds @main struct AdsTestApp: App { let adManager = InterstitialAdsManager.shared init(){ initMobileAds() } var body: some Scene { WindowGroup { HomeView() } } func initMobileAds() { GADMobileAds.sharedInstance().start(completionHandler: nil) GADMobileAds.sharedInstance().disableSDKCrashReporting() InterstitialAdsManager.shared.loadInterstitialAd() } }
HomeView代码
import SwiftUI struct HomeView: View { @State var showAd: Bool = true var body: some View { NavigationStack{ VStack { NavigationLink(destination: ContentView(showAd: $showAd)){ Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text("To Content") } } .padding() } } } #Preview { HomeView() }
ContentView代码
import SwiftUI struct ContentView: View { @Binding var showAd: Bool let adsManager = InterstitialAdsManager.shared var body: some View { ZStack() { NavigationLink { SettingsView() } label: { Label("To Settings", systemImage: "slider.horizontal.3") .font(.title) .frame(maxWidth: .infinity, maxHeight: .infinity ) } } .background(.yellow) .onAppear(){ if(showAd){ adsManager.displayInterstitialAd() } showAd.toggle() } } }
SettingsView代码
import SwiftUI struct SettingsView: View { var body: some View { VStack() { Text("Hello, World!") .font(.title) .frame(maxWidth: .infinity, maxHeight: .infinity ) .padding(.all) } .background(.green) } } #Preview { SettingsView() }
InterstitialAdManager代码
import Foundation import GoogleMobileAds class InterstitialAdsManager: NSObject, GADFullScreenContentDelegate, ObservableObject { // Properties @Published var interstitialAdLoaded:Bool = false var interstitialAd:GADInterstitialAd? static let shared = InterstitialAdsManager() override init() { super.init() } func loadInterstitialAd(){ GADInterstitialAd.load(withAdUnitID: "ca-app-pub-3940256099942544/4411468910", request: GADRequest()) { [weak self] add, error in guard let self = self else {return} if let error = error{ print("🔴: \(error.localizedDescription)") self.interstitialAdLoaded = false return } #if DEBUG print("🟢: Ad Loading succeeded") #endif self.interstitialAdLoaded = true self.interstitialAd = add self.interstitialAd?.fullScreenContentDelegate = self } } func displayInterstitialAd(){ let scenes = UIApplication.shared.connectedScenes let windowScene = scenes.first as? UIWindowScene let window = windowScene?.windows.first guard let root = window?.rootViewController else { return } if let ad = interstitialAd{ ad.present(fromRootViewController: root) self.interstitialAdLoaded = false }else{ print("🔵: Ad not ready") self.interstitialAdLoaded = false self.loadInterstitialAd() } } // Failure notification func ad(_ ad: GADFullScreenPresentingAd, didFailToPresentFullScreenContentWithError error: Error) { #if DEBUG print("🟡: Failed to display interstitial ad: \(error.localizedDescription)") #endif self.loadInterstitialAd() } // Indicate notification func adWillPresentFullScreenContent(_ ad: GADFullScreenPresentingAd) { #if DEBUG print("🤩: Displayed an interstitial ad") #endif self.interstitialAdLoaded = false } // Close notification func adDidDismissFullScreenContent(_ ad: GADFullScreenPresentingAd) { #if DEBUG print("😔: Interstitial ad closed") #endif self.loadInterstitialAd() } }
内容的提问来源于stack exchange,提问作者zBandit
相关产品推荐
相关产品推荐

