How to display ads within a collection view

会有一股神秘感。 提交于 2019-12-21 04:10:53

问题


I'm trying to add some banner ads randomly inside my collectionView.

Each collectionView cell would be a basic image (black square here to make things easier) populated dynamically from an array (let's say it's a really long array and call it "longDataArray") that I would get from the web.

I could manage to add some banner ads to my collectionView but the problem is that it's breaking the order of my longDataArray. For example, just for testing when I'm adding an ad banner at indexPath 6, then the ad banner correctly shows up at indexPath 6, and I'm able to manage the width change for the cell, but the image corresponding at the indexPath 6 for my longDataArray would obviously never appears.

I also could do it spliting my longDataArray in two, and then playing with the sections : section 0 = firstPartOfArray, section 1 = ad banner, and section 2 = secondPartOfArray. But this takes a lot of effort creating differents arrays and sections, just to add only one ad banner, and it's obviously not what I'm looking for.

So my question is, how would you add banner ad within your collectionView (only one section), but keeping the indexPath logic ?

I googled a lot about that, and was surprised that I could not come up with any solution for this problem.

Do you guys have any idea ?

Thanks!


回答1:


Hi I have created a collectionView inside the table cell with same requirement, You can check my code.

//
//  ViewController.swift
//  DemoApp
//
//  Created by Mahesh Kumar on 09/01/18.
//  Copyright © 2018 Mahesh Kumar. All rights reserved.
import UIKit

class TableCell : UITableViewCell{
    @IBOutlet weak var collVw: UICollectionView!
    @IBOutlet weak var categoryName: UILabel!
}

class ViewController: UIViewController, UICollectionViewDelegate,UICollectionViewDataSource , UICollectionViewDelegateFlowLayout , UITableViewDelegate,UITableViewDataSource {

    var categories_array = ["Home","Helth","New","Home1","Home2","Home3","Home4","Home5","Home6","Home7","Home8","Home9","Home11","Home12","Home13","Home14","Home15"]

    //Mark
    var sectionArray = NSMutableArray()


    @IBOutlet weak var tableVw: UITableView!
    override func viewDidLoad() {
        super.viewDidLoad()

        //Mark
        var sectionCount = 0
        var mainIndex = 0

        let section = categories_array.count % 4
        if(section == 0){
            sectionCount =  categories_array.count/4
        }
        else{
             sectionCount =  categories_array.count/4 + 1
        }
        //Mark
        for _ in 0...sectionCount {
            let rowsData = NSMutableArray()
            var j = 0
            while  j<4{
                if(mainIndex == categories_array.count){
                    break
                }
                rowsData.add(categories_array[mainIndex])
                j = j + 1
                mainIndex = mainIndex + 1

            }
          sectionArray.add(rowsData)


        }

        tableVw.reloadData()

        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 3
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableVw.dequeueReusableCell(withIdentifier: "cell1", for: indexPath) as? TableCell

        if(indexPath.row == 1){
            cell?.categoryName.text = "Top Redeemed"
        }
        else if(indexPath.row == 2){
            cell?.categoryName.text = "Categories"
        }

        cell?.collVw.tag  = indexPath.row
        cell?.collVw.delegate = self
        cell?.collVw.dataSource = self
        cell?.collVw.reloadData()

        return cell!
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

        return 400
    }


    func numberOfSections(in collectionView: UICollectionView) -> Int {
        if(collectionView.tag == 0){
              return 1
        }
        else if(collectionView.tag == 1){
            if(categories_array.count > 4){
            if(categories_array.count % 4 == 0){
                return categories_array.count/4
            }
            else{
                return (categories_array.count/4) + 1
            }
            }
            else{
                return 1
            }

        }
        else{
            return 10
        }


    }
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
        cell.backgroundColor = UIColor.green
        if let lbl = cell.viewWithTag(1) as? UILabel{
            lbl.text = "\(indexPath.row)"
        }
        return cell

    }
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
    {
        if(collectionView.tag == 0){
             return CGSize.init(width:  collectionView.frame.width - 10, height: collectionView.frame.height)
        }
        else if(collectionView.tag == 1){
            return CGSize.init(width:  (collectionView.frame.width)/2 - 5.5, height: collectionView.frame.height/2 - 0.5)

        }
       else {
            return CGSize.init(width:  collectionView.frame.width/3 - 4, height: collectionView.frame.height/2 - 0.5)
        }

    }


    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        if(collectionView.tag == 0){
            return 10
        }
        else{
            return 1
        }
    }

   func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets
   {
       return UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
   }




    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        if(collectionView.tag == 0){
           return 10
        }
         else if(collectionView.tag == 1){
            return ((sectionArray[section] as? NSMutableArray)?.count)!
        }
         else{
             return 6
        }

    }

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        print("coll vw",indexPath.row)
        print(indexPath.section)

        //Mark
        if(collectionView.tag == 1){
            print(collectionView.tag)
            let array = sectionArray[indexPath.section] as? NSMutableArray
            print(array![indexPath.row])
        }

    }


}



回答2:


So my question is, how would you add banner ad within your collectionView (only one section), but keeping the indexPath logic ?

You just need to adjust the index path to account for the ads. For example, let's say that you want every 15th cell to contain an ad. Let's use 1-based arithmetic here to make the math intuitive. Cells 1-14 will just get their regular content, cell 15 will have an ad, cells 16-29 will get the content for items 15-28, cell 30 will get another ad, and so on. So, your -collectionView:cellForItemAtIndexPath: method would need to figure out whether the index path refers to an ad cell (in which case the 1-based item number is evenly divisible by 15) or a content cell (every other cell). In the latter case, it'd also need to adjust the item number to get the right content.

NSInteger item = indexPath.item + 1;   // switch to 1-based numbering
if (item % 15 == 0) {
    // we have an ad cell, so return a cell configured with an ad
}
else {
    item = item - (item / 15); // subtract the ad cells
    item -= 1;                 // switch back to 0-based indexes
    // return a cell configured with the data at index `item`
}

You'd also have to do corresponding calculations in other methods that deal with cells, such as -collectionView:numberOfItemsInSection:. For that reason, it'd probably be a good idea to write some utility methods that would make the adjustments.




回答3:


For UICollectionView you have to two custom UICollectionView

  1. Cell1 is for the Imageview.
  2. Cell2 is for the the banner ad.

In cellForItem

if (indexPath.item == 6){
    // dequeue your cell2 here
    return cell2
}
else{
    // dequeue your cell1 here
    return cell1
}

Implement UICollection​View​Delegate​Flow​Layout and use like this

func collectionView(_ collectionView: UICollectionView, 
                      layout collectionViewLayout: UICollectionViewLayout, 
               sizeForItemAt indexPath: IndexPath) -> CGSize{

  if (indexPath.item == 6){
      return CGSizeMake(60,60)
  }
  else{
      return CGSizeMake([[UIScreen mainScreen] bounds].size.width, 60.0)
  }

}

To display ad in your app, you AdMob




回答4:


We succeeded that developed an example for with Ersin for this issue.

You can check it out here.

https://github.com/Cemoo/WaterFlowLayout



来源:https://stackoverflow.com/questions/43062278/how-to-display-ads-within-a-collection-view

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!