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
相关产品推荐
相关产品推荐

