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

SwiftUI中UIViewController封装的AdMob Banner占用过多空间问题

解决SwiftUI中AdMob横幅广告视图过度拉伸的问题

官方示例里的BannerContentView(基于UIViewControllerRepresentable)会默认撑满父容器的可用空间,导致Spacer失效,核心原因是UIViewController的view默认会填充所有可用布局空间,且没有向SwiftUI传递正确的广告视图尺寸。以下是具体修改方案:

步骤1:修改BannerViewController,传递正确尺寸

在负责承载广告的BannerViewController中,监听广告加载完成事件,将广告视图的实际尺寸设为控制器的preferredContentSize,让SwiftUI感知到正确的高度:

class BannerViewController: UIViewController {
    var bannerView: GADBannerView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // 初始化横幅广告视图,使用标准横幅尺寸
        bannerView = GADBannerView(adSize: GADAdSizeBanner)
        bannerView.adUnitID = "你的广告单元ID"
        bannerView.rootViewController = self
        bannerView.delegate = self
        view.addSubview(bannerView)
        
        // 设置约束:让广告视图居中,高度跟随自身尺寸
        bannerView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            bannerView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            bannerView.topAnchor.constraint(equalTo: view.topAnchor),
            bannerView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
        ])
        
        bannerView.load(GADRequest())
    }
}

// 实现广告代理,更新控制器尺寸
extension BannerViewController: GADBannerViewDelegate {
    func bannerViewDidReceiveAd(_ bannerView: GADBannerView) {
        // 广告加载完成后,同步控制器的理想尺寸为广告视图的实际大小
        preferredContentSize = bannerView.bounds.size
    }
}

步骤2:修改BannerContentView,适配SwiftUI布局

让BannerContentView遵循UIViewControllerRepresentable的同时,实现sizeThatFits方法,返回控制器的preferredContentSize,告诉SwiftUI使用这个尺寸布局:

struct BannerContentView: UIViewControllerRepresentable {
    let navigationTitle: String
    
    func makeUIViewController(context: Context) -> BannerViewController {
        let vc = BannerViewController()
        vc.title = navigationTitle
        return vc
    }
    
    func updateUIViewController(_ uiViewController: BannerViewController, context: Context) {}
    
    // 关键:让SwiftUI使用控制器返回的理想尺寸
    func sizeThatFits(_ proposal: ProposedViewSize, uiViewController: BannerViewController, context: Context) -> CGSize? {
        uiViewController.preferredContentSize
    }
}

步骤3:正常使用即可

修改后的BannerContentView会自动适配广告的实际高度,不会再撑满空间,Spacer也能正常工作:

struct SomeScreen: View {
    var body: some View {
        VStack {
            Text("Some text")
            Spacer()
            BannerContentView(navigationTitle: "Banner").background(.red)
        }
    }
}

补充说明

如果广告加载前需要占位,可以在BannerViewController中设置默认的preferredContentSize为标准横幅高度(比如CGSize(width: UIScreen.main.bounds.width, height: 50)),避免布局跳动。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 22:47:35