Swift:无法关闭视图控制器



我有一个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
}
}