SwiftUI:Admob Interstitial Ad 未在 rootViewController 上呈现

SwiftUI: Admob Interstitial Ad is not being presented on rootViewController

用 SWIFTUI 编码

我在我的 SwiftUI 应用程序中实现了一个设置页面,该页面在单击视图中的按钮时显示。此视图包含在 sheet 中。您可以看到下面的代码:

TabsBar(showOptionsTab: $showOptionsTab)
    .sheet(isPresented: $showOptionsTab)
    {
        OptionsTab(showOptionsTab: self.$showOptionsTab)
    }

我在此 "OptionsTab" 中实现了一个插页式广告,它是在 .onAppear() 调用中加载选项选项卡时创建的,并在选择后退按钮时显示。您可以从下面的 OptionsTab 中获取代码:

@State private var interstitial : GADInterstitial!

VStack
{
    ... other code

    Button(action:
    {
        if ( self.interstitial.isReady)
        { 
            let root = UIApplication.shared.windows.first?.rootViewController
            self.interstitial.present(fromRootViewController: root!)               
        }

        self.showOptionsTab.toggle()
    })
    {
        Image(systemName: "xmark")
            .font(.largeTitle)
    }
}
.onAppear
{
    self.interstitial = GADInterstitial(adUnitID: "addID")
    let req = GADRequest()
    self.interstitial.load(req) 
}

我在记录插页式广告状态的按钮中有额外的代码,它显示它已准备就绪,并且正在点击当前代码...但它从未出现。

我已经在 ContentView 中实现了这个确切的代码,并且插页式加载非常好。 sheet 中的此代码导致插页式广告不显示。

在 sheet 显示的视图中,rootViewController 是否是加载插页式广告的不正确视图?不然我哪里做错了?

提前感谢您的帮助!

试试这个

TabsBar(showOptionsTab: $showOptionsTab)
    .sheet(isPresented: $showOptionsTab)
    {
        OptionsTab(showOptionsTab: self.$showOptionsTab)
            .OnDisapear 
            {    
                if ( self.interstitial.isReady)
                { 
                    let root = UIApplication.shared.windows.first?.rootViewController
                    self.interstitial.present(fromRootViewController: root!)               
                }
            } 
        }
    }

然后在此视图中添加状态插页式变量,并在 ContextView 的 onAppear 中创建插页式变量。

解决方案 2:

(未测试但应该有效): 出现在 presentingViewController 而不是 rootViewController

  if ( self.interstitial.isReady)
        { 
            let root = UIApplication.shared.windows.first?.rootViewController?.presentingViewController
            self.interstitial.present(fromRootViewController: root!)               
        }

检查原因,在答案的最后

解决方案 1:

听起来好像有一些东西可以阻止在 sheet 视图已经呈现时呈现插页式广告

在我的例子中,我想在呈现 sheet 视图后立即呈现广告,但这不起作用

有效的是,展示广告,在它被关闭后,sheet 视图将被呈现,它成功了!

对于插页式广告,我使用了此代码

import SwiftUI
import GoogleMobileAds
import UIKit

final class Interstitial:NSObject, GADInterstitialDelegate{
  var interstitialID = "ca-app-pub-3940256099942544/4411468910"
  var interstitial:GADInterstitial = GADInterstitial(adUnitID: "ca-app-pub-3940256099942544/4411468910")
  var sheet: (() -> Void)? = nil  //this closure will be executed after dismissing the ad

  override init() {
    super.init()
    LoadInterstitial()
  }

  func LoadInterstitial(){
    let req = GADRequest()
    self.interstitial.load(req)
    self.interstitial.delegate = self
  }

  func showAd(then sheet:(() -> Void)?){
    if self.interstitial.isReady{
      let root = UIApplication.shared.windows.first?.rootViewController
      self.interstitial.present(fromRootViewController: root!)
      self.sheet = sheet
    }
    else{
      print("Not Ready")
    }
  }

  func interstitialDidDismissScreen(_ ad: GADInterstitial) {
    self.interstitial = GADInterstitial(adUnitID: interstitialID)
    LoadInterstitial()
    if let presentSheet = sheet {
      presentSheet()
    }
  }
}

在这里我们将我们想要发生的任何事情传递给将在调用 interstitialDidDismissScreen 时调用的闭包

现在不再按按钮切换状态,而是在广告关闭后切换

在您的 contentView 顶部:

    struct HistoryView: View {
      private var fullScreenAd: Interstitial!
    init() {
fullScreenAd = Interstitial()
}
    }

然后在您的按钮中:

   Button(action: {
            self.interstitial.showAd {
              self.showOptionsTab.toggle()

            }              

        })

Note: i used the code of interstitial Ad from this gist

Also, AFAIK we can't tell if it's an bug in swiftUI, or it's something googleAdmob was supposed to take care of ?, there's no SwiftUI support From google so we can't blame them.

AFAIK 的问题,在 iOS 13 中,抓住根 ViewController 将 return 显示 sheet 的视图控制器,并在尝试显示广告,UIKit 会抱怨你试图呈现一个视图控制器,而视图控制器已经存在(sheet), 解决方案 ?简单,在呈现的视图控制器上呈现广告(The sheet)