1

用 SWIFTUI 编码

我在我的 SwiftUI 应用程序中实现了一个设置页面,该页面在单击视图中的按钮时显示。这个视图被包裹在一张纸中。你可以看到下面的代码:

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 中实现了这个确切的代码,并且插页式加载非常好。工作表中有关此代码的某些内容导致插页式广告不显示。

在从工作表呈现的视图中,rootViewController 是否是加载插页式广告的不正确视图?否则,我还做错了什么?

我在这里先向您的帮助表示感谢!

4

2 回答 2

2

尝试这个

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,在那里创建插页式。

于 2020-04-10T23:29:28.913 回答
0

解决方案2:

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

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

检查原因,在答案的最后

解决方案1:

听起来好像有一些东西阻止了在已经呈现工作表视图时呈现插页式广告

就我而言,我想在呈现工作表视图后立即呈现广告,但这不起作用

有效的是,展示广告,在它被关闭后,将展示工作表视图,并且它有效!

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

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()

            }              

        })

注意:我使用了这个gist中的插页式广告代码

此外,AFAIK 我们无法判断这是 swiftUI 中的错误,还是 googleAdmob 应该处理的问题?谷歌不支持 SwiftUI,所以我们不能责怪他们。

问题 AFAIK,在 iOS 13 中,抓取根 ViewController 将返回呈现工作表的视图控制器,并且在尝试呈现广告时,UIKit 会抱怨您正在尝试呈现视图控制器,而视图控制器已经存在(表),解决方案?简单,在呈现的视图控制器(工作表)上呈现广告

于 2020-05-01T00:11:55.220 回答