struct BottomBannerView : View {
@State var isLoaded: Bool = true
var body : some View{
AdViewBottom(isLoaded: self.$isLoaded)
.frame(width: 320, height: isLoaded ? 50 : 0)
}
}
struct AdViewBottom: UIViewRepresentable {
@Binding var isLoaded: Bool
class Coordinator: NSObject, GADBannerViewDelegate {
func bannerView(_ bannerView: GADBannerView, didFailToReceiveAdWithError error: Error) {
print("Ad failed to load: \(error.localizedDescription)")
isLoaded = false // HOW???
}
}
func makeCoordinator() -> Coordinator {
Coordinator()
}
func makeUIView(context: Context) -> GADBannerView {
let banner = GADBannerView(adSize: GADAdSizeBanner)
banner.adUnitID = "ca-app-pub-xxx~xxxx"
// banner.rootViewController = UIApplication.shared.windows.first?.rootViewController // The root view controller is needed to present full screen content.
banner.delegate = context.coordinator
banner.load(GADRequest())
banner.backgroundColor = .black
return banner
}
// SwiftUI calls this method to update the GADBannerView.
func updateUIView(_ uiView: GADBannerView, context: Context) {
// In this case, no update is needed.
}
}
I need to hide the AD when it fails to load, I can't update isLoaded
from within the class Coordinator
, so how to do this correctly?
You can pass the AdViewBottom
instance directly via Coordinator
constructor and then toggle the Bool
property if needed, something like:
class Coordinator: NSObject, GADBannerViewDelegate {
let adView: AdViewBottom
init(_ adView: AdViewBottom) {
self.adView = adView
}
func bannerView(_ bannerView: BannerView, didFailToReceiveAdWithError error: Error) {
adView.isLoaded = false
}
}
struct AdViewBottom: UIViewRepresentable {
...
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
}