SwiftUI项目中AdMob原生广告Callout按钮集成问题求助
SwiftUI集成AdMob原生广告:Callout按钮点击逻辑实现
在SwiftUI项目中集成AdMob原生广告后,广告内容已正常显示,但不清楚如何实现Callout按钮的点击逻辑。以下是现有代码及广告展示效果:
广告状态枚举与加载管理类
enum AdStatus { case loading, success, failure } final class NativeViewController2: NSObject, ObservableObject, GADNativeAdLoaderDelegate, GADNativeAdDelegate { @Published var adStatus: AdStatus = .loading var adLoader: GADAdLoader? var nativeAd: GADNativeAd? // 广告单元ID let adUnitID = Pub.AdMob.nativeAdUnitId func loadAd(adStatus: AdStatus){ self.adStatus = adStatus let options = GADNativeAdMediaAdLoaderOptions() options.mediaAspectRatio = .square let root = UIApplication .shared .connectedScenes .flatMap { ($0 as? UIWindowScene)?.windows ?? [] } .first { $0.isKeyWindow }!.rootViewController adLoader = GADAdLoader(adUnitID: adUnitID, rootViewController: root!, adTypes: [GADAdLoaderAdType.native], options: [options]) adLoader?.delegate = self adLoader?.load(GADRequest()) } func adLoader(_ adLoader: GADAdLoader, didReceive nativeAd: GADNativeAd) { // 设置原生广告代理,监听广告事件 nativeAd.delegate = self self.nativeAd = nativeAd self.adStatus = .success print("广告加载成功") } func adLoader(_ adLoader: GADAdLoader, didFailToReceiveAdWithError error: Error) { self.adStatus = .failure print("广告加载失败") } func nativeAds() -> GADNativeAd? { self.nativeAd } }
广告展示SwiftUI视图
struct NativeView: View { @State var adStatus: AdStatus @State var nativeViewController = NativeViewController2() var body: some View { VStack { if nativeViewController.adStatus == .success { if let nativeAd = nativeViewController.nativeAds() { NativeAdView2(nativeAd: nativeAd) .frame(height: 140, alignment: .center) } } } .onAppear { nativeViewController.loadAd(adStatus: adStatus) } } } struct NativeAdView2: View { var nativeAd: GADNativeAd var body: some View { VStack { HStack { Spacer() Text("广告") .font(.system(size: 11, weight: .semibold, design: .rounded)) .padding(.horizontal, 5) .foregroundColor(.white) .background( RoundedRectangle(cornerRadius: 5) .fill(Color(#colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1))) ) } .padding(.horizontal, 15) .padding(.bottom, -10) HStack { Image(uiImage: (nativeAd.icon?.image)!) .resizable() .scaledToFill() .frame(width: 65, height: 65) .cornerRadius(5) VStack(alignment: .leading) { Text(nativeAd.headline!) .fontWeight(.semibold) .fixedSize(horizontal: false, vertical: true) .font(.body) .lineLimit(2) .lineSpacing(1) Text(nativeAd.advertiser ?? "广告主") .font(.subheadline) } Spacer() } .padding(.horizontal, 15) HStack(spacing: 15) { Text(nativeAd.price ?? "") if let starRating = nativeAd.starRating { HStack { ForEach(0..<Int(truncating: starRating), id: \.self) { _ in Image(systemName: "star") } } } if let cTA = nativeAd.callToAction { Button(action: { // 待实现点击逻辑 }, label: { Text(cTA) .padding(.horizontal, 10) .padding(.vertical, 5) .background( RoundedRectangle(cornerRadius: 10) .fill(Color(.systemBlue)) ) .foregroundColor(.white) }) } } .font(.subheadline) } .modifier(forEachDesign()) .frame(height: 140, alignment: .center) .background(BlurView(style: .dark)) .cornerRadius(10) } }
广告展示效果

实现Callout按钮点击逻辑的步骤
由于SwiftUI视图并非直接的UIKit视图,需要手动关联AdMob的点击追踪逻辑,具体实现如下:
1. 添加视图追踪工具
创建一个ViewModifier,用来获取SwiftUI视图对应的UIKit UIView实例,供AdMob调用点击方法使用:
struct ViewTracker: ViewModifier { @Binding var trackedView: UIView? func body(content: Content) -> some View { content .background(UIViewRepresentableHelper(view: $trackedView)) } } struct UIViewRepresentableHelper: UIViewRepresentable { @Binding var view: UIView? func makeUIView(context: Context) -> UIView { let view = UIView() self.view = view return view } func updateUIView(_ uiView: UIView, context: Context) {} }
2. 修改NativeAdView2实现点击逻辑
在NativeAdView2中引入视图追踪,并在按钮点击时调用AdMob原生广告的performClick方法:
struct NativeAdView2: View { var nativeAd: GADNativeAd // 存储追踪到的UIView实例 @State private var adContainerView: UIView? var body: some View { VStack { // 原有广告内容... if let cTA = nativeAd.callToAction { Button(action: { guard let containerView = adContainerView else { return } // 调用AdMob的点击方法,传入对应的视图 nativeAd.performClick(on: containerView) // 可选:记录广告曝光(若未在其他地方调用) nativeAd.recordImpression() }, label: { Text(cTA) .padding(.horizontal, 10) .padding(.vertical, 5) .background( RoundedRectangle(cornerRadius: 10) .fill(Color(.systemBlue)) ) .foregroundColor(.white) }) } } // 添加视图追踪modifier .modifier(ViewTracker(trackedView: $adContainerView)) .modifier(forEachDesign()) .frame(height: 140, alignment: .center) .background(BlurView(style: .dark)) .cornerRadius(10) } }
关键说明
performClick(on:)是AdMob处理原生广告点击的核心方法,必须传入UIView实例用于事件追踪;recordImpression()用于统计广告曝光数据,若在广告加载完成后已调用过,此处可省略;- 确保已设置
nativeAd.delegate(现有代码中已在adLoader(_:didReceive:)中完成设置),AdMob会自动处理后续跳转逻辑。
内容的提问来源于stack exchange,提问作者dibs
相关产品推荐
相关产品推荐

