The SDK provides a universal way to display advertisements inside the cell of scrollable controls, such as UITableView
and UICollectionView
.
We need you to edit your item Layout, so it has a wrapper/holder for the Ads. This is because we can not edit your data for adding new items to the adapter, so we take the existing item views and add the ads to them. You can customize which items have ads when you create the configuration for the infinite scroll. |
import UIKit import R89SDK class TableViewInfiniteScrollViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { var tableView:UITableView! ... override func viewDidLoad() { super.viewDidLoad() tableView = UITableView(frame: self.view.bounds, style: .plain) // Table view configurations. tableView.register(InfScrlViewCell.self, forCellReuseIdentifier: "cell") tableView.delegate = self tableView.dataSource = self tableView.estimatedRowHeight = 300 tableView.rowHeight = UITableView.automaticDimension self.view.addSubview(tableView) NSLayoutConstraint.activate([ tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor), tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor), tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor) ]) ... } ... } |
The adWrapper
will play the role of a wrapper inside the cell's contentView
.
class InfScrlViewCell: UITableViewCell { let label = UILabel() // This is the wrapper let adWrapper:UIView = { let view = UIView() // Specify the item ad tag here view.accessibilityLabel = "infiniteScroll_ad_wrapper_tag" return view }() override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) contentView.addSubview(label) // Added the wrapper to the item contentView.addSubview(adWrapper) // Setup the constraints ... } ... } |
class TableViewInfiniteScrollViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { var tableView:UITableView! ... override func viewDidLoad() { super.viewDidLoad() tableView = UITableView(frame: self.view.bounds, style: .plain) // Table view configurations. ... // Show the ads. let infiniteScrollConfigId = ConfigBuilder.companion.INFINITE_SCROLL_TEST_R89_CONFIG_ID RefineryAdFactory.shared.createInfiniteScroll( configurationID: infiniteScrollConfigId, scrollView: tableView, // Specify the item ad tag here as well scrollItemAdWrapperTag: "infiniteScroll_ad_wrapper_tag", lifecycleCallbacks: nil ) } ... } |
import UIKit import R89SDK class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { var collectionView: UICollectionView! ... override func viewDidLoad() { super.viewDidLoad() // Configure the collection view layout let layout = UICollectionViewFlowLayout() layout.scrollDirection = .vertical layout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize // Configure the collection view collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) collectionView.dataSource = self collectionView.delegate = self collectionView.register(DynamicHeightCollectionViewCell.self, forCellWithReuseIdentifier: "cell") // Add constraints to fill the view collectionView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(collectionView) NSLayoutConstraint.activate([ collectionView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor), collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor), collectionView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor) ]) } ... } |
The adWrapper
will play the role of a wrapper inside the cell’s contentView
.
class DynamicHeightCollectionViewCell: UICollectionViewCell { let label = UILabel() let adWrapper: UIView = { let view = UIView() // Specify the item ad tag here view.accessibilityLabel = "infiniteScroll_ad_wrapper_tag" return view }() override init(frame: CGRect) { super.init(frame: frame) contentView.addSubview(label) // Added the wrapper to the item contentView.addSubview(adWrapper) // Setup the constraints ... } ... } |
import UIKit import R89SDK class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { var collectionView: UICollectionView! ... override func viewDidLoad() { super.viewDidLoad() // Configure the collection view layout ... let infiniteScrollConfigId = ConfigBuilder.companion.INFINITE_SCROLL_TEST_R89_CONFIG_ID RefineryAdFactory.shared.createInfiniteScroll( configurationID: infiniteScrollConfigId, scrollView: self.collectionView, scrollItemAdWrapperTag: "infiniteScroll_ad_wrapper_tag", lifecycleCallbacks: nil) } ... } |
Your They can be many or none depending on your requests, if you need one or more please request them to your account manager or technical account manager. |
When not using a UITableView or UIControllerView we need to create the infinite scroll manually and use the returned id to show ads for each cell position.
let infiniteScrollConfigId = ConfigBuilder.companion.INFINITE_SCROLL_TEST_R89_CONFIG_ID let infiniteScrollId = RefineryAdFactory.shared.createManualInfiniteScroll( configurationID: infiniteScrollConfigId, lifecycleCallbacks: nil) |
Your They can be many or none depending on your requests, if you need one or more please request them to your account manager or technical account manager. |
class ManualInfScrollViewCell: UIView { let label = UILabel() let adWrapper = UIView() ... override init(frame: CGRect) { super.init(frame: frame) addSubview(label) // Added the wrapper to the item addSubview(adWrapper) // Setup the constraints ... } ... } |
Then in each cell, you will need to get the wrapper instance adWrapper
and use it to request the ad for the cell position.
let cellPosition = manualInfScrollViewCell.getPosition() let adWrapper = manualInfScrollViewCell.adWrapper RefineryAdFactory.shared.getInfiniteScrollAdForIndex( infiniteScrollId: infiniteScrollId, itemIndex: Int32(cellPosition), itemAdWrapper: adWrapper, childAdLifecycle: nil ) |
Careful on the implementation of This needs to be implemented according to your implementation of the infinite scroll. EX: 20 items per page so first 20 items go from 0 to 19 and the first item of the second page is not 0 is 20 formula beeing -> pageItemIndex + (pageSize*currentPage) so first item position of first page is 0 + (20*0) item 0 plus 20 multiplied by the current page index, so page 1 has index 0 and first item position of the second page is 0 + (20*1) item 0 plus 20 multiplied by the current page index, so page 2 has index 1 second item first page would be 1 + (20*0) = 1 second item second page would be 1 + (20*1) = 21 and so on |
You can subscribe to these events with the same method but passing a new object as a parameter. Details about this object can be found in the Reference.
import UIKit import R89SDK // 1. Extend from the InfiniteScrollEventListener class InfiniteScrollLifecycleListener: InfiniteScrollEventListener { ... override func onAdItemLoaded(itemIdInData: Int32) { // Ad has been loaded for the position } ... } class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { var collectionView: UICollectionView! ... override func viewDidLoad() { super.viewDidLoad() // Configure the collection view layout ... let infiniteScrollConfigId = ConfigBuilder.companion.INFINITE_SCROLL_TEST_R89_CONFIG_ID RefineryAdFactory.shared.createInfiniteScroll( configurationID: infiniteScrollConfigId, scrollView: self.collectionView, scrollItemAdWrapperTag: "infiniteScroll_ad_wrapper_tag", // 2. Pass the InfiniteScrollLifecycleListener instance via lifecycleCallbacks lifecycleCallbacks: InfiniteScrollLifecycleListener()) } ... } |
The same lifecycleCallbacks
parameter is available for the createInfiniteScroll
and createManualInfiniteScroll
methods.
While using the manual approach additionally ad lifecycle methods could be observed for each cell/item providing the BannerEventListener
’s instance to getInfiniteScrollAdForIndex
method in the following way
// 1. Extend from the BannerEventListener private class BannerLifecycleListener : BannerEventListener { ... override func onLoaded() { // Ad has been loaded } ... } ... RefineryAdFactory.shared.getInfiniteScrollAdForIndex( infiniteScrollId: infiniteScrollId, itemIndex: Int32(cellPosition), itemAdWrapper: adWrapper, childAdLifecycle: BannerLifecycleListener() ) ... |