Skip to content

Commit 981174b

Browse files
Merge pull request #170 from teads/adOpportunityTrackerView_reuseCell
implement adOpportunityTrackerView into reusable cells
2 parents 94f5fa3 + 03992d6 commit 981174b

File tree

5 files changed

+107
-19
lines changed

5 files changed

+107
-19
lines changed

TeadsSampleApp.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
E9984EF926B2D46F000D42D3 /* FakeArticleNativeTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9984EF526B2D46F000D42D3 /* FakeArticleNativeTableViewCell.swift */; };
4646
E9984EFA26B2D46F000D42D3 /* MoPubNativeTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9984EF626B2D46F000D42D3 /* MoPubNativeTableViewCell.swift */; };
4747
E9984EFB26B2D46F000D42D3 /* AdmobNativeAdTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9984EF726B2D46F000D42D3 /* AdmobNativeAdTableViewCell.swift */; };
48+
E9A3AC582795AF2C00F124D6 /* AdOpportunityTrackerTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9A3AC572795AF2C00F124D6 /* AdOpportunityTrackerTableViewCell.swift */; };
49+
E9A3AC5A2795BB0D00F124D6 /* AdOpportunityTrackerCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9A3AC592795BB0D00F124D6 /* AdOpportunityTrackerCollectionViewCell.swift */; };
4850
E9A6F4BD26B7188D005C5F78 /* NativeAdCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9A6F4BC26B7188D005C5F78 /* NativeAdCollectionViewCell.swift */; };
4951
F71C452127918A88000C696F /* TeadsSampleAppUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F71C452027918A88000C696F /* TeadsSampleAppUITests.swift */; };
5052
F7651FE326A07A58004DAFD9 /* bootstrap.js in Resources */ = {isa = PBXBuildFile; fileRef = F7651FE126A07A58004DAFD9 /* bootstrap.js */; };
@@ -104,6 +106,8 @@
104106
E9984EF526B2D46F000D42D3 /* FakeArticleNativeTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FakeArticleNativeTableViewCell.swift; sourceTree = "<group>"; };
105107
E9984EF626B2D46F000D42D3 /* MoPubNativeTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoPubNativeTableViewCell.swift; sourceTree = "<group>"; };
106108
E9984EF726B2D46F000D42D3 /* AdmobNativeAdTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AdmobNativeAdTableViewCell.swift; sourceTree = "<group>"; };
109+
E9A3AC572795AF2C00F124D6 /* AdOpportunityTrackerTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdOpportunityTrackerTableViewCell.swift; sourceTree = "<group>"; };
110+
E9A3AC592795BB0D00F124D6 /* AdOpportunityTrackerCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdOpportunityTrackerCollectionViewCell.swift; sourceTree = "<group>"; };
107111
E9A6F4BC26B7188D005C5F78 /* NativeAdCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NativeAdCollectionViewCell.swift; sourceTree = "<group>"; };
108112
F71C451E27918A88000C696F /* TeadsSampleAppUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TeadsSampleAppUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
109113
F71C452027918A88000C696F /* TeadsSampleAppUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TeadsSampleAppUITests.swift; sourceTree = "<group>"; };
@@ -200,6 +204,7 @@
200204
isa = PBXGroup;
201205
children = (
202206
B502BA121F827D5C008257EC /* InReadDirectTableViewController.swift */,
207+
E9A3AC572795AF2C00F124D6 /* AdOpportunityTrackerTableViewCell.swift */,
203208
);
204209
path = TableView;
205210
sourceTree = "<group>";
@@ -216,6 +221,7 @@
216221
isa = PBXGroup;
217222
children = (
218223
40077B422534AABF00D53197 /* InReadDirectCollectionViewController.swift */,
224+
E9A3AC592795BB0D00F124D6 /* AdOpportunityTrackerCollectionViewCell.swift */,
219225
);
220226
path = CollectionView;
221227
sourceTree = "<group>";
@@ -687,6 +693,7 @@
687693
buildActionMask = 2147483647;
688694
files = (
689695
B5966D1E269D8FC6005CA2FF /* InReadAdmobScrollViewController.swift in Sources */,
696+
E9A3AC582795AF2C00F124D6 /* AdOpportunityTrackerTableViewCell.swift in Sources */,
690697
B56A8ABB2698A0A20090A14A /* InReadDirectTableViewController.swift in Sources */,
691698
E9984EFA26B2D46F000D42D3 /* MoPubNativeTableViewCell.swift in Sources */,
692699
B50425D0252E078B00ABF07D /* String.swift in Sources */,
@@ -700,6 +707,7 @@
700707
E906CDA926B81D4200E92576 /* MoPubNativeAdView.swift in Sources */,
701708
408A2D4A253D995200CCFF44 /* RootHeaderCollectionReusableView.swift in Sources */,
702709
E9A6F4BD26B7188D005C5F78 /* NativeAdCollectionViewCell.swift in Sources */,
710+
E9A3AC5A2795BB0D00F124D6 /* AdOpportunityTrackerCollectionViewCell.swift in Sources */,
703711
E9984EFB26B2D46F000D42D3 /* AdmobNativeAdTableViewCell.swift in Sources */,
704712
408A2D4B253D995200CCFF44 /* RootImageViewLabelCollectionViewCell.swift in Sources */,
705713
B5966D1C269C7690005CA2FF /* InReadDirectCollectionViewController.swift in Sources */,
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//
2+
// AdOpportunityTrackerCollectionViewCell.swift
3+
// TeadsSampleApp
4+
//
5+
// Created by Paul Nicolas on 17/01/2022.
6+
// Copyright © 2022 Teads. All rights reserved.
7+
//
8+
9+
import UIKit
10+
import TeadsSDK
11+
12+
/// Implement this cell to track slot
13+
class AdOpportunityTrackerCollectionViewCell: UICollectionViewCell {
14+
static let identifier = "AdOpportunityTrackerCollectionViewCellIdentifier"
15+
func setTrackerView(_ trackerView: TeadsAdOpportunityTrackerView) {
16+
contentView.addSubview(trackerView)
17+
}
18+
}

TeadsSampleApp/Controllers/InRead/Direct/CollectionView/InReadDirectCollectionViewController.swift

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,30 @@ import TeadsSDK
1111

1212
class InReadDirectCollectionViewController: TeadsViewController {
1313

14+
enum TeadsElement: Equatable {
15+
case article
16+
case ad(_ ad: TeadsInReadAd)
17+
case trackerView(_ trackerView: TeadsAdOpportunityTrackerView)
18+
}
19+
1420
@IBOutlet weak var collectionView: UICollectionView!
1521

1622
let contentCell = "TeadsContentCell"
1723
let teadsAdCellIndentifier = "TeadsAdCell"
1824
let fakeArticleCell = "fakeArticleCell"
19-
let adItemNumber = 2
25+
let trackerViewItemNumber = 2 // tracker view needs to be placed above the slot view
26+
var adItemNumber: Int {
27+
return trackerViewItemNumber + 1
28+
}
2029
var placement: TeadsInReadAdPlacement?
2130

22-
private var elements = [TeadsInReadAd?]()
31+
private var elements = [TeadsElement]()
2332

2433
override func viewDidLoad() {
2534
super.viewDidLoad()
2635

2736
(0..<8).forEach { _ in
28-
elements.append(nil)
37+
elements.append(.article)
2938
}
3039

3140
let placementSettings = TeadsAdPlacementSettings { (settings) in
@@ -36,6 +45,8 @@ class InReadDirectCollectionViewController: TeadsViewController {
3645
placement?.requestAd(requestSettings: TeadsAdRequestSettings { settings in
3746
settings.pageUrl("https://www.teads.tv")
3847
})
48+
49+
collectionView.register(AdOpportunityTrackerCollectionViewCell.self, forCellWithReuseIdentifier: AdOpportunityTrackerCollectionViewCell.identifier)
3950
}
4051

4152
@objc func rotationDetected() {
@@ -48,12 +59,15 @@ class InReadDirectCollectionViewController: TeadsViewController {
4859
}
4960

5061
func closeSlot(ad: TeadsAd) {
51-
elements.removeAll { $0 == ad }
62+
guard let inReadAd = ad as? TeadsInReadAd else {
63+
return
64+
}
65+
elements.removeAll { $0 == .ad(inReadAd) }
5266
collectionView.reloadData()
5367
}
5468

5569
func updateAdSize(ad: TeadsInReadAd) {
56-
if let row = elements.firstIndex(of: ad) {
70+
if let row = elements.firstIndex(of: .ad(ad)) {
5771
collectionView.reloadItems(at: [IndexPath(row: row, section: 0)])
5872
collectionView.collectionViewLayout.invalidateLayout()
5973
}
@@ -69,12 +83,16 @@ extension InReadDirectCollectionViewController: UICollectionViewDelegate, UIColl
6983
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
7084
if indexPath.item == 0 {
7185
return collectionView.dequeueReusableCell(withReuseIdentifier: contentCell, for: indexPath)
72-
} else if let ad = elements[indexPath.row] {
86+
} else if case let .ad(ad) = elements[indexPath.row] {
7387
let cellAd = collectionView.dequeueReusableCell(withReuseIdentifier: teadsAdCellIndentifier, for: indexPath)
7488
let teadsAdView = TeadsInReadAdView(bind: ad)
7589
cellAd.contentView.addSubview(teadsAdView)
7690
teadsAdView.setupConstraintsToFitSuperView(horizontalMargin: 10)
7791
return cellAd
92+
} else if case let .trackerView(trackerView) = elements[indexPath.row],
93+
let cellAd = collectionView.dequeueReusableCell(withReuseIdentifier: AdOpportunityTrackerCollectionViewCell.identifier, for: indexPath) as? AdOpportunityTrackerCollectionViewCell {
94+
cellAd.setTrackerView(trackerView)
95+
return cellAd
7896
} else {
7997
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: fakeArticleCell, for: indexPath)
8098
return cell
@@ -88,10 +106,12 @@ extension InReadDirectCollectionViewController: UICollectionViewDelegate, UIColl
88106
return CGSize.zero
89107
}
90108
return CGSize(width: collectionView.bounds.width, height: bounds.height)
91-
} else if let ad = elements[indexPath.row] {
109+
} else if case let .ad(ad) = elements[indexPath.row] {
92110
let width = collectionView.frame.width - 20
93111
let height = ad.adRatio.calculateHeight(for: width)
94112
return .init(width: width, height: height)
113+
} else if case .trackerView(_) = elements[indexPath.row] {
114+
return .init(width: 1, height: 0)
95115
} else {
96116
return CGSize(width: collectionView.bounds.width, height: 300)
97117
}
@@ -119,13 +139,12 @@ extension InReadDirectCollectionViewController: TeadsAdDelegate {
119139
func didClose(ad: TeadsAd) {
120140
closeSlot(ad: ad)
121141
}
122-
123142
}
124143

125144
extension InReadDirectCollectionViewController: TeadsInReadAdPlacementDelegate {
126145

127146
func didReceiveAd(ad: TeadsInReadAd, adRatio: TeadsAdRatio) {
128-
elements.insert(ad, at: adItemNumber)
147+
elements.insert(.ad(ad), at: adItemNumber)
129148
let indexPaths = [IndexPath(row: adItemNumber, section: 0)]
130149
collectionView.insertItems(at: indexPaths)
131150
collectionView.collectionViewLayout.invalidateLayout()
@@ -141,6 +160,9 @@ extension InReadDirectCollectionViewController: TeadsInReadAdPlacementDelegate {
141160
}
142161

143162
func adOpportunityTrackerView(trackerView: TeadsAdOpportunityTrackerView) {
144-
//not relevant in tableView integration
163+
elements.insert(.trackerView(trackerView), at: trackerViewItemNumber)
164+
let indexPaths = [IndexPath(row: trackerViewItemNumber, section: 0)]
165+
collectionView.insertItems(at: indexPaths)
166+
collectionView.collectionViewLayout.invalidateLayout()
145167
}
146168
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//
2+
// AdOpportunityTrackerTableViewCell.swift
3+
// TeadsSampleApp
4+
//
5+
// Created by Paul Nicolas on 17/01/2022.
6+
// Copyright © 2022 Teads. All rights reserved.
7+
//
8+
9+
import UIKit
10+
import TeadsSDK
11+
12+
/// Implement this cell to track slot
13+
class AdOpportunityTrackerTableViewCell: UITableViewCell {
14+
static let identifier = "AdOpportunityTrackerTableViewCellIndentifier"
15+
func setTrackerView(_ trackerView: TeadsAdOpportunityTrackerView) {
16+
contentView.addSubview(trackerView)
17+
}
18+
}

TeadsSampleApp/Controllers/InRead/Direct/TableView/InReadDirectTableViewController.swift

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,25 @@ class InReadDirectTableViewController: TeadsViewController {
1616
let contentCell = "TeadsContentCell"
1717
let teadsAdCellIndentifier = "TeadsAdCell"
1818
let fakeArticleCell = "fakeArticleCell"
19-
let adRowNumber = 3
19+
let trackerViewRowNumber = 3 // tracker view needs to be placed above the slot view
20+
var adRowNumber: Int {
21+
return trackerViewRowNumber + 1
22+
}
2023
var placement: TeadsInReadAdPlacement?
2124

22-
private var elements = [TeadsInReadAd?]()
25+
enum TeadsElement: Equatable {
26+
case article
27+
case ad(_ ad: TeadsInReadAd)
28+
case trackerView(_ trackerView: TeadsAdOpportunityTrackerView)
29+
}
30+
31+
private var elements = [TeadsElement]()
2332

2433
override func viewDidLoad() {
2534
super.viewDidLoad()
2635

2736
(0..<8).forEach { _ in
28-
elements.append(nil)
37+
elements.append(.article)
2938
}
3039

3140
let placementSettings = TeadsAdPlacementSettings { (settings) in
@@ -36,10 +45,15 @@ class InReadDirectTableViewController: TeadsViewController {
3645
placement?.requestAd(requestSettings: TeadsAdRequestSettings { settings in
3746
settings.pageUrl("https://www.teads.tv")
3847
})
48+
49+
tableView.register(AdOpportunityTrackerTableViewCell.self, forCellReuseIdentifier: AdOpportunityTrackerTableViewCell.identifier)
3950
}
4051

4152
func closeSlot(ad: TeadsAd) {
42-
elements.removeAll { $0 == ad }
53+
guard let inReadAd = ad as? TeadsInReadAd else {
54+
return
55+
}
56+
elements.removeAll { $0 == .ad(inReadAd) }
4357
tableView.reloadData()
4458
}
4559

@@ -57,21 +71,27 @@ extension InReadDirectTableViewController: UITableViewDelegate, UITableViewDataS
5771
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
5872
if indexPath.row == 0 {
5973
return tableView.dequeueReusableCell(withIdentifier: contentCell, for: indexPath)
60-
} else if let ad = elements[indexPath.row] {
74+
} else if case let .ad(ad) = elements[indexPath.row] {
6175
let cellAd = tableView.dequeueReusableCell(withIdentifier: teadsAdCellIndentifier, for: indexPath)
6276
let teadsAdView = TeadsInReadAdView(bind: ad)
6377
cellAd.contentView.addSubview(teadsAdView)
6478
teadsAdView.setupConstraintsToFitSuperView(horizontalMargin: 10)
6579
return cellAd
80+
} else if case let .trackerView(trackerView) = elements[indexPath.row],
81+
let cellAd = tableView.dequeueReusableCell(withIdentifier: AdOpportunityTrackerTableViewCell.identifier, for: indexPath) as? AdOpportunityTrackerTableViewCell {
82+
cellAd.setTrackerView(trackerView)
83+
return cellAd
6684
} else {
6785
let cell = tableView.dequeueReusableCell(withIdentifier: fakeArticleCell, for: indexPath)
6886
return cell
6987
}
7088
}
7189

7290
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
73-
if let ad = elements[indexPath.row] {
91+
if case let .ad(ad) = elements[indexPath.row] {
7492
return ad.adRatio.calculateHeight(for: tableView.frame.width - 20)
93+
} else if case .trackerView(_) = elements[indexPath.row] {
94+
return 0
7595
}
7696
return UITableView.automaticDimension
7797
}
@@ -81,7 +101,7 @@ extension InReadDirectTableViewController: UITableViewDelegate, UITableViewDataS
81101
extension InReadDirectTableViewController: TeadsInReadAdPlacementDelegate {
82102

83103
func didReceiveAd(ad: TeadsInReadAd, adRatio: TeadsAdRatio) {
84-
elements.insert(ad, at: adRowNumber)
104+
elements.insert(.ad(ad), at: adRowNumber)
85105
ad.delegate = self
86106
let indexPaths = [IndexPath(row: adRowNumber, section: 0)]
87107
tableView.insertRows(at: indexPaths, with: .automatic)
@@ -92,14 +112,16 @@ extension InReadDirectTableViewController: TeadsInReadAdPlacementDelegate {
92112
}
93113

94114
func didUpdateRatio(ad: TeadsInReadAd, adRatio: TeadsAdRatio) {
95-
if let row = elements.firstIndex(of: ad) {
115+
if let row = elements.firstIndex(of: .ad(ad)) {
96116
tableView.reloadRows(at: [IndexPath(row: row, section: 0)], with: .automatic)
97117
}
98118

99119
}
100120

101121
func adOpportunityTrackerView(trackerView: TeadsAdOpportunityTrackerView) {
102-
//not relevant in tableView integration
122+
elements.insert(.trackerView(trackerView), at: trackerViewRowNumber)
123+
let indexPaths = [IndexPath(row: trackerViewRowNumber, section: 0)]
124+
tableView.insertRows(at: indexPaths, with: .automatic)
103125
}
104126

105127
}

0 commit comments

Comments
 (0)