Some GADUnifiedNativeAdViews Are Not Clickable (AdMob/Swift)

Published

I am implementing AdMob’s Native Advanced ads into my iOS app. I use a UICollectionViewCell that contains a GADUnifiedNativeAdView​ and from there, I set up my ads in the viewDidLoad() and cellForItemAt()​…

The Code

override func viewDidLoad() {
        let adUnitID = "ca-app-pub-3940256099942544/3986624511"
        let numAdsToLoad = 5
        let options = GADMultipleAdsAdLoaderOptions()
        options.numberOfAds = numAdsToLoad
        
        let adOptions = GADNativeAdViewAdOptions()
        adOptions.preferredAdChoicesPosition = .topRightCorner
        
        adLoader = GADAdLoader(adUnitID: adUnitID, rootViewController: self, adTypes: [.unifiedNative], options: [options, adOptions])
        adLoader.delegate = self
        adLoader.load(GADRequest())
}

func adLoader(_ adLoader: GADAdLoader, didReceive nativeAd: GADUnifiedNativeAd) {
        nativeAds.append(nativeAd)
}
    
func adLoaderDidFinishLoading(_ adLoader: GADAdLoader) {
        collectionView.reloadData()
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "onlineAdCell", for: indexPath) as! OnlineAdCollectionViewCell

        let nativeAd = nativeAds[onlineAdIndex()]
        nativeAd.rootViewController = self
        (cell.adView.headlineView as! UILabel).text = nativeAd.headline
        (cell.adView.callToActionView as! UILabel).text = nativeAd.callToAction
                   (cell.adView.imageView as! UIImageView).image = nativeAd.images?.first?.image
                    cell.adView.imageView?.contentMode = .scaleAspectFill
        cell.adView.callToActionView?.isUserInteractionEnabled = false
        cell.adView.nativeAd = nativeAd
        return cell
}

The Problem

So this works almost perfectly. The problem is that, for whatever reason, only some of the ads are actually clickable. So here’s what a clickable ad looks like in my UI:

Screenshot of clickable ad

and here’s what a non-clickable ad looks like:

Screenshot of non-clickable ad

As you can tell the only difference is the ad info icon in the top right-hand corner.

Does anyone have any idea as to why this would be happening and any troubleshooting solutions? It’s quite confusing…

Source: Ios

Published
Categorised as admob, ios, swift, uicollectionview

Answers

That might be happening because UICollectionViews reuse cells especially if you’ve got 5+ cells depending on their sizes. adloader is probably detecting views (GADUnifiedNativeAdView) from cells which are still nil and make them invalid.

The first solution would be to load one ad at the time and display them from the view cells which are almost going to be visible :

 func adLoader(_ adLoader: GADAdLoader, didReceive nativeAd: GADUnifiedNativeAd) {
    let indexPath = IndexPath(item: YOUR_RANDOM_INDEX, section: 0)

  guard let cell = collectionView.cellForItem(at: indexPath) as?  OnlineAdCollectionViewCell else {
        return
    } 

    nativeAd.rootViewController = self
    (cell.adView.headlineView as! UILabel).text = nativeAd.headline
    (cell.adView.callToActionView as! UILabel).text = nativeAd.callToAction
               (cell.adView.imageView as! UIImageView).image = nativeAd.images?.first?.image
                cell.adView.imageView?.contentMode = .scaleAspectFill
    cell.adView.callToActionView?.isUserInteractionEnabled = false
    cell.adView.nativeAd = nativeAd
collectionView.reloadItems(at: [indexPath])


 }     



 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "onlineAdCell", for: indexPath) as! OnlineAdCollectionViewCell

    return cell

  }

Or detect the cells that are about to be displayed and assign them your native ads:

 func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
    print("WILL DISPLAY CELL -> \(indexPath.item)")  // cell that is about to be displayed

    guard let cell = collectionView.cellForItem(at: indexPath) as? OnlineAdCollectionViewCell else { return }

let nativeAd = nativeAds[onlineAdIndex()]
    nativeAd.rootViewController = self
    (cell.adView.headlineView as! UILabel).text = nativeAd.headline
    (cell.adView.callToActionView as! UILabel).text = nativeAd.callToAction
               (cell.adView.imageView as! UIImageView).image = nativeAd.images?.first?.image
                cell.adView.imageView?.contentMode = .scaleAspectFill
    cell.adView.callToActionView?.isUserInteractionEnabled = false
    cell.adView.nativeAd = nativeAd
 collectionView.reloadItems(at: [indexPath])

}


func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "onlineAdCell", for: indexPath) as! OnlineAdCollectionViewCell

return cell
     }

Barney Ullrich Jr.

Leave a Reply

Your email address will not be published. Required fields are marked *

Still Have Questions?


Our dedicated development team is here for you!

We can help you find answers to your question for as low as 5$.

Contact Us
faq