我有一个SwiftUI项目,其中我展示了一个视图控制器,通过MoPub显示广告。
一切都按预期工作,除了一件事:当我点击广告的关闭按钮时,广告本身关闭,但广告后面的黑屏继续显示。我想视图控制器没有被关闭(但dismiss
的完成块确实运行了)。
这是我的代码:
class InterstitialAds: UIViewController, MPInterstitialAdControllerDelegate {
var moPubView: MPInterstitialAdController?
func viewControllerForPresentingModalView() -> UIViewController! {
return self
}
//Called when you tap the ad's close button:
func interstitialWillDismiss(_ interstitial: MPInterstitialAdController) {
dismissControllerWithoutReward()
}
func showAd() {
let topViewController = UIApplication.shared.windows.filter {$0.isKeyWindow}.first?.rootViewController
self.modalPresentationStyle = .fullScreen
topViewController?.present(self, animated: true) {}
}
func dismissControllerWithoutReward() {
self.dismiss(animated: true) {
print("dismissControllerWithoutReward()") //Successfully prints to console
}
}
override func viewDidLoad() {
let adId = "4f117153f5c24fa6a3a92b818a5eb630" //Test ad unit
self.moPubView = MPInterstitialAdController(forAdUnitId: adId)
if let v = self.moPubView {
v.delegate = self
v.loadAd()
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
v.show(from: self)
}
}
super.viewDidLoad()
}
}
问:尽管成功调用了dismiss
,为什么视图控制器没有被关闭?
谢谢!
编辑:有趣的是,如果我在尝试关闭视图控制器之前等待 0.5 秒,它会根据需要关闭。所以,现在我已经interstitialWillDismiss(_:)
有了这段代码(但我仍然想知道为什么会发生这种情况):
func interstitialWillDismiss(_ interstitial: MPInterstitialAdController) {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self.dismissControllerWithoutReward()
}
}
为了获得清晰的实现和预期行为,您应该将InterstitialAds
控制器包装在UIViewControllerRepresentable
中,然后将 SwiftUI 端与一些通过一些isPresented
标志绑定从UIViewControllerRepresentable
实现的InterstitialAdsView
连接起来。
简短示例:
class InterstitialAds: UIViewController {
let onFlowCompleted: () -> Void
init(onFlowCompleted: @escaping () -> Void) {
self.onFlowCompleted = onFlowCompleted
// ...
}
override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
onFlowCompleted()
// or somewhere else ...
}
}
struct HomeView: View {
@State var shouldShowInterstitialView = false
var body: some View {
Button {
shouldShowInterstitialView = true
} label: {
Text("Show Ad")
}
.fullScreenCover(isPresented: $shouldShowInterstitialView) {
InterstitialAdsView {
shouldShowInterstitialView = false
}
}
}
}
struct InterstitialAdsView: UIViewControllerRepresentable {
// @Environment(.presentationMode) var presentationMode
// or
// @Binding var isPresented: Bool
// or
let onFlowCompleted: () -> Void
func makeUIViewController(context: Context) -> InterstitialAds {
InterstitialAds(onFlowCompleted: onFlowCompleted)
}
func updateUIViewController(_ uiViewController: InterstitialAds, context: Context) {
// update if needed
}
}