0

I'm adding my bannerView inside a collectionView header. It won't let me set the bannerView.rootViewController as self to the headerView because it's not a UIViewController.

enter image description here

I can always implement the required properties inside the viewController that has the collectionView but then how do I load the bannerView?

class HeaderView: UICollectionReusableView {

    var bannerView: GADBannerView = {
        let view = GADBannerView()
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = .white

        bannerView = GADBannerView(adSize: kGADAdSizeSmartBannerPortrait)

        bannerView.adUnitID = "ca-app-pub-3940256099942544/2934735716"
        bannerView.rootViewController = self
        bannerView.load(GADRequest())
    }
}

class that contains the collectionView:

class MainViewController: UIViewController {

    var collectionView: UICollectionView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // ... instantiate the collectionView
    }

    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {

        let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "headerView", for: indexPath) as! HeaderView

        return headerView
    }
}
Lance Samaria
  • 17,576
  • 18
  • 108
  • 256

1 Answers1

0

Inside the headerView I added a PassthroughView and inside cellForItem I added the bannerView as subView to the PassthroughView. It works fine

import GoogleMobileAds

class HeaderView: UICollectionReusableView {

    var passthroughView: PassthroughView = {
        let view = PassthroughView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.isUserInteractionEnabled = true
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = .white

        // anchors for passthroughView ...
    }

    func addBannerViewToPassthroughView(_ bannerView: GADBannerView) {

        if !bannerView.isDescendant(of: passthroughView) {

            passthroughView.addSubview(bannerView)
        }
    }
}

The class that contains the collectionView and serves the ads are in the main vc and NOT the cell so I don't have to worry about the cell recycling itself and constantly serving ads as it's scrolled:

class MainViewController: UIViewController {

    var collectionView: UICollectionView!

    var bannerView: GADBannerView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // ... instantiate the collectionView

        bannerView = GADBannerView(adSize: kGADAdSizeSmartBannerPortrait)
        bannerView.adUnitID = "ca-app-pub-3940256099942544/2934735716"
        bannerView.rootViewController = self
        bannerView.delegate = self
        bannerView.load(GADRequest())
    }

    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {

        let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "headerView", for: indexPath) as! HeaderView

        // for some strange reason adding the bannerView as a subView to the passthroughView inconsistently froze my app (sometimes it did and sometimes it didn't). Once I added it on the mainQueue everything worked fine
        DispatchQueue.main.async { [weak self] in
            if let bannerView = self?.bannerView {
                headerView.addBannerViewToPassthroughView(bannerView)
            }
        }

        return headerView
    }
}

Follow this answer for more info on how the bannerView knows when it is and isn't on screen.

Lance Samaria
  • 17,576
  • 18
  • 108
  • 256
  • Try adding the view directly as a subview in your header. I don't think there is need for PassThroughView – Sahil Manchanda Aug 08 '19 at 04:35
  • what's the matter with the passthroughview? it works fine, I've been scrolling up and down and no problems – Lance Samaria Aug 08 '19 at 04:37
  • PassThroughView was needed if you wanted to pass touch events to view/controls beneath it. whereas if your directly add it as a subview just like you are doing it in your answer but instead directly. then there is no need of passthroughview. – Sahil Manchanda Aug 08 '19 at 04:40
  • I gotcha. In my actual project I rounded the corners to the ad so it looks more native with all the other objects that have rounded corners. It was easier to just add a view then to try and round the corners of the header itself. Thanks for the tip though, much appreciated! Cheers!!! :) – Lance Samaria Aug 08 '19 at 04:43