0

So I want to add ads inside my UIcollectionView. After every 4th folder, I want to show an ad (for a total of 3 times,hence the row 4,9 and 14).

I've tried the following:

  override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        if indexPath.row == 4 || indexPath.row == 9 || indexPath.row == 14 {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "AdUnitsCollectionViewCell", for: indexPath) as? AdUnitsCollectionViewCell
            //cell?.addSubview(AdUnitController().getBannerView(2))
            //cell?.view = AdUnitController().getBannerView(2)
            cell?.view.adUnitID = "/6499/example/banner"
            cell?.view.rootViewController = self
            cell?.view.load(DFPRequest())
            return cell!
        } else {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FolderViewCellIdentifier, for: indexPath) as? FolderViewCell
        cell!.configure(folders![indexPath.row])
        return cell!
        }
    }

This does indeed show the ads 3 times after every 4th folder, but now my folder for that indexPath.row isn't shown anymore (4, 9 and 14). Is there a way I can add my ads inside the collectionview AND my folders as well?

Thanks!

SoundShock
  • 485
  • 1
  • 3
  • 24
  • You need to add +3 in your `numberOfRowsInSection` method of your tableViewDataSource – Reinier Melian Apr 04 '17 at 14:51
  • See also [How to display ads within a collection view](http://stackoverflow.com/q/43062278/643383) – Caleb Apr 04 '17 at 14:55
  • @ReinierMelianwish it was that easy. gives me an Index is out of bounds (must be less than 187)' because on indexpath.row I only place one cell, but not the other – SoundShock Apr 04 '17 at 14:56

2 Answers2

1

First of all you must have to increase total number of item/row if you want to add it inside collection view (which will be total_folder + total_add) but as @bhmahler said : Just adding the number of rows is not enough, you then need to account for the negative offset

What you can do is you can keep a count of how many time it went inside the if block, if it went inside this block increase the count

if indexPath.row == 4 || indexPath.row == 9 || indexPath.row == 14 {
   count+=1 //which is initially set to zero 
}

Now in your else block you can simply minus the count from index path, like this

else {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FolderViewCellIdentifier, for: indexPath) as? FolderViewCell
        cell!.configure(folders![indexPath.row-count])
        return cell!
    }

Make sure to set count=0 outside of collection view delegate methods

Sorry for the incomplete code as I don't know swift.Hope it helps

Mahbub Ahmed
  • 196
  • 1
  • 8
-1

You will need to increase the number of rows if you want to show both an ad AND the folder

override func numberOfItems(inSection section: Int) -> Int {
   let count = //the count you were using before
   return count + floor(count/4) //add an ad every 4
}

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    if indexPath.row % 4 == 0 && indexPath.row > 0 {  //assuming you don't want an ad as the first item
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "AdUnitsCollectionViewCell", for: indexPath) as? AdUnitsCollectionViewCell
        //cell?.addSubview(AdUnitController().getBannerView(2))
        //cell?.view = AdUnitController().getBannerView(2)
        cell?.view.adUnitID = "/6499/example/banner"
        cell?.view.rootViewController = self
        cell?.view.load(DFPRequest())
        return cell!
    } else {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FolderViewCellIdentifier, for: indexPath) as? FolderViewCell
        cell!.configure(folders![indexPath.row])
        return cell!
    }
}

EDIT

A more holistic approach would be to modify your folders array(?) to support both AdUnitsCollectionViewCell and FolderViewCell data.
For example, if folders is an array of structs as

struct CellData {
    static enum CellDataType {
        case folder
        case ad
    }
    let type: CellDataType
    let data: //some type - you haven't shown whats required
}

There will need to be a method that injects an ad every 4 into the folders array and then you can switch on folders[indexPath.row].type to decide if you want to show an ad cell or a folder cell. You don't need to modify the numberOfItemsInSection method either.

dmorrow
  • 5,152
  • 5
  • 20
  • 31
  • 2
    This may result in indexes outside the size of the collection on folders. Just adding the number of rows is not enough, you then need to account for the negative offset when configuring your actual cells. Otherwise you are just skipping rows in the folders collection and will eventually end up outside the bounds of the folder collection – hawkstrider Apr 04 '17 at 14:52
  • @bhmahler We can't be expected to write the entire class for him. He hasn't shared what the `folders` data looks like either. I think this is helpful to get him going in the right direction. – dmorrow Apr 04 '17 at 15:09
  • this will result in folder being out range of course ! – Sameh Aug 16 '19 at 09:10