SwiftUI TabView中AdMob横幅广告的合理放置方案问询
Hey there! Let's fix that AdMob banner issue with your SwiftUI TabView. The key goals here are: keep the banner persistent across tab switches, place it directly above the TabBar without content overlap, and avoid the hassle of calculating offsets manually. Here's a robust approach:
Step 1: Get the Exact TabBar Height
First, we need to reliably fetch the full height of the TabBar (including safe area insets) across all devices and orientations. We'll use a UIViewRepresentable to access the underlying UITabBar:
struct TabBarHeightReader: UIViewRepresentable { @Binding var height: CGFloat func makeUIView(context: Context) -> UIView { let view = UIView() DispatchQueue.main.async { // Traverse up the view hierarchy to find the UITabBar if let tabBar = view.superview?.superview as? UITabBar { height = tabBar.frame.height } } return view } func updateUIView(_ uiView: UIView, context: Context) {} }
Step 2: Build the Main View Structure
We'll use a TabView with:
- Padding on each child view to avoid content overlap with the banner
- An overlay for the persistent AdMob banner, positioned using the exact TabBar height
- Handling for orientation changes to adjust banner size
struct MainTabView: View { @State private var tabBarHeight: CGFloat = 0 private let bannerPortraitHeight = kGADAdSizeSmartBannerPortrait.size.height private let bannerLandscapeHeight = kGADAdSizeSmartBannerLandscape.size.height var body: some View { TabView { // Your first tab view View1() .padding(.bottom, currentBannerHeight) .tabItem { Image(systemName: "person.fill") Text("My Jobs") } // Your second tab view View2() .padding(.bottom, currentBannerHeight) .tabItem { Image(systemName: "clock") Text("Shifts") } } // Inject the TabBar height reader .overlay(TabBarHeightReader(height: $tabBarHeight)) // Add the persistent banner above the TabBar .overlay( GeometryReader { geo in AdView() .frame( width: geo.size.width, height: currentBannerHeight ) } .offset(y: -tabBarHeight), alignment: .bottom ) // Update banner height when orientation changes .onReceive(NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)) { _ in // Trigger a view update to refresh banner height self.tabBarHeight = self.tabBarHeight } } private var currentBannerHeight: CGFloat { UIDevice.current.orientation.isPortrait ? bannerPortraitHeight : bannerLandscapeHeight } }
How This Solves Your Problems
- No More Manual Offset Calculations: The
TabBarHeightReadergrabs the actual height of the TabBar, so the banner always sits perfectly above it—regardless of device or orientation. - No Content Overlap: Each child view gets bottom padding equal to the banner height, ensuring content never gets blocked by the ad (which keeps you compliant with AdMob policies).
- Persistent Banner: The banner is added as an overlay to the entire
TabView, not individual tabs, so it stays loaded and visible when switching between views.
Bonus Tips
- Make sure your
AdViewis set up to handle adaptive sizes (AdMob will automatically adjust the ad content to fit the frame we provide). - Test across multiple devices and orientations to confirm the banner stays in place and content remains accessible.
内容的提问来源于stack exchange,提问作者James Woodcock
相关产品推荐
相关产品推荐

