You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中Ad Mob横幅广告加载失败时如何隐藏以不占屏幕空间?

解决SwiftUI横幅广告加载失败时不占用空间的问题

你遇到的核心问题是:仅隐藏BannerView无法让外层SwiftUI视图释放空间,因为SwiftUI层不知道广告加载失败的状态。需要把UIKit层的广告加载状态传递到SwiftUI层,让视图根据状态动态调整布局。

以下是具体修改步骤:

1. 给BannerAdVC添加加载状态绑定

在UIKit控制器中新增绑定属性,用于通知SwiftUI广告的加载状态:

class BannerAdVC: UIViewController, GADBannerViewDelegate {
    let adUnitId: String
    @Binding var isAdLoaded: Bool // 新增绑定属性

    init(adUnitId: String, isAdLoaded: Binding<Bool>) {
        self.adUnitId = adUnitId
        self._isAdLoaded = isAdLoaded
        super.init(nibName: nil, bundle: nil)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    var bannerView: GADBannerView = GADBannerView()
    
    override func viewDidLoad() {
        bannerView.delegate = self
        bannerView.adUnitID = adUnitId
        bannerView.rootViewController = self
        view.addSubview(bannerView)
    }
    
    // ... 原有viewDidAppear、viewWillTransition、loadBannerAd代码保持不变
}

2. 实现广告加载状态的代理方法

补充GADBannerViewDelegate的关键方法,更新加载状态并处理BannerView显示:

// 广告加载成功时触发
func bannerViewDidReceiveAd(_ bannerView: GADBannerView) {
    isAdLoaded = true
    bannerView.isHidden = false
}

// 广告加载失败时触发
func bannerView(_ bannerView: GADBannerView, didFailToReceiveAdWithError error: Error) {
    print("Failed to receive ad: \(error.localizedDescription)")
    isAdLoaded = false
    bannerView.isHidden = true
    bannerView.backgroundColor = .clear
}

3. 修改BannerAd组件传递状态

更新UIViewControllerRepresentable组件,添加绑定属性并传递给控制器:

struct BannerAd: UIViewControllerRepresentable {
    let adUnitId: String
    @Binding var isAdLoaded: Bool // 新增绑定属性

    init(adUnitId: String, isAdLoaded: Binding<Bool>) {
        self.adUnitId = adUnitId
        self._isAdLoaded = isAdLoaded
    }
    
    func makeUIViewController(context: Context) -> BannerAdVC {
        return BannerAdVC(adUnitId: adUnitId, isAdLoaded: $isAdLoaded)
    }
    
    func updateUIViewController(_ uiViewController: BannerAdVC, context: Context) {
        // 可根据需求添加视图更新逻辑
    }
}

4. 调整SwiftUIBannerAd的布局逻辑

在SwiftUI视图中添加加载状态变量,根据状态动态显示广告或空视图:

public struct SwiftUIBannerAd: View {
    @State var height: CGFloat = 0
    @State var width: CGFloat = 0
    @State var adPosition: AdPosition
    let adUnitId: String
    @State private var isAdLoaded = false // 新增加载状态变量

    public init(adPosition: AdPosition, adUnitId: String) {
        self.adPosition = adPosition
        self.adUnitId = adUnitId
    }
    
    public enum AdPosition {
        case top
        case bottom
    }
    
    public var body: some View {
        VStack {
            if adPosition == .bottom {
                Spacer()
            }

            // 根据加载状态切换显示内容
            if isAdLoaded {
                BannerAd(adUnitId: adUnitId, isAdLoaded: $isAdLoaded)
                    .frame(width: width, height: height, alignment: .center)
            } else {
                EmptyView()
                    .frame(height: 0) // 失败时高度设为0,不占用空间
            }
            
            if adPosition == .top {
                Spacer()
            }
        }
        .onAppear {
            setFrame()
        }
        .onReceive(NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)) { _ in
            setFrame()
        }
    }
    
    func setFrame() {
        let safeAreaInsets = UIApplication.shared.windows.first(where: { $0.isKeyWindow })?.safeAreaInsets ?? .zero
        let frame = UIScreen.main.bounds.inset(by: safeAreaInsets)

        let adSize = GADCurrentOrientationAnchoredAdaptiveBannerAdSizeWithWidth(frame.width)

        self.width = adSize.size.width
        self.height = adSize.size.height
    }
}

5. 优化外部调用代码(可选)

现在SwiftUIBannerAd会自动处理加载失败的隐藏逻辑,外部调用可以简化:

HStack {
    Spacer()
    SwiftUIBannerAd(adPosition: .top, adUnitId: StaticCodes.bannerCode)
        .padding()
    Spacer()
}

修改完成后,广告加载失败时,SwiftUI会显示高度为0的空视图,完全不占用屏幕空间;加载成功则正常展示横幅广告。

内容的提问来源于stack exchange,提问作者RinaredStaring

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 12:47:50