如何在当前集合视图中显示 xib
How to display xib in current collection view
这是我第一次使用 Google AdMob 原生广告,我相信我遵循了实施说明。剩下的就是在集合视图中实际显示广告,这就是我所在的位置卡住。我不知道如何在上传的用户之间正确显示广告 post。基本上我需要帮助将 xib 添加到集合视图。任务:滚动浏览 posts..
时应填充广告
我正在使用
集合视图
西布
Google AdMob 原生高级
我也没有收到任何错误或崩溃,控制台打印,所以我显然做错了什么。收到原生广告:
控制台也 - print
("Ads not dispalying ") 和 print
("Not what I want")
这是我的代码
import UIKit
import Firebase
class FollowingFeedViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UISearchBarDelegate, FeedCellDelegate, PeopleToFollowDelegate, GADUnifiedNativeAdLoaderDelegate {
// MARK: - Google ADMob
/// The ad unit ID from the AdMob UI.
let adUnitID = "ca-app-pub-3940256099942544/3986624511"
/// The number of native ads to load (between 1 and 5 for this example).
let numAdsToLoad = 5
/// The native ads.
var nativeAds = [GADUnifiedNativeAd]()
/// The ad loader that loads the native ads.
var adLoader: GADAdLoader!
func adLoaderDidFinishLoading(_ adLoader: GADAdLoader) {
addNativeAds()
}
func adLoader(_ adLoader: GADAdLoader, didReceive nativeAd: GADUnifiedNativeAd) {
print("Received native ad: \(nativeAd)")
// Add the native ad to the list of native ads.
nativeAds.append(nativeAd)
}
func adLoader(_ adLoader: GADAdLoader, didFailToReceiveAdWithError error: GADRequestError) {
print("\(adLoader) failed with error: \(error.localizedDescription)")
}
/// Add native ads to the list.
func addNativeAds() {
if nativeAds.count <= 0 {
print("Ads not dispalying ")
return
}
let adInterval = (posts.count / nativeAds.count) + 1
var index = 0
for nativeAd in nativeAds {
if index < collectionObject.count {
collectionObject.insert(nativeAd, at: index)
index += adInterval
} else {
print("Not what I want")
break
}
}
}
// MARK: - Properties
var posts = [Post]()
var collectionObject = [AnyObject]()
var viewSinglePost = false
var post: Post?
var currentKey: String?
var userProfileController: ProfileViewController?
var header: FeedReusableView?
@IBOutlet weak var collectionView: UICollectionView!
// MARK: - UICollectionViewDataSource
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if posts.count > 4 {
if indexPath.item == posts.count - 1 {
fetchPosts()
}
}
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return posts.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PostsCell", for: indexPath) as? FollowingCell {
cell.delegate = self
cell.post = posts[indexPath.item] as Post
handleUsernameLabelTapped(forCell: cell)
handleMentionTapped(forCell: cell)
handleHashtagTapped(forCell: cell)
return cell
} else {
let nativeAd = collectionObject[indexPath.row] as! GADUnifiedNativeAd
nativeAd.rootViewController = self
let nativeAdCell = collectionView.dequeueReusableCell(withReuseIdentifier: "UnifiedNativeAdCell", for: indexPath)
// Get the ad view from the Cell. The view hierarchy for this cell is defined in
let adView : GADUnifiedNativeAdView = nativeAdCell.contentView.subviews
.first as! GADUnifiedNativeAdView
// Associate the ad view with the ad object.
// This is required to make the ad clickable.
adView.nativeAd = nativeAd
adView.mediaView?.mediaContent = nativeAd.mediaContent
// Populate the ad view with the ad assets.
(adView.headlineView as! UILabel).text = nativeAd.headline
(adView.advertiserView as! UILabel).text = nativeAd.advertiser
(adView.bodyView as! UILabel).text = nativeAd.body
adView.bodyView?.isHidden = nativeAd.body == nil
(adView.iconView as? UIImageView)?.image = nativeAd.icon?.image
adView.iconView?.isHidden = nativeAd.icon == nil
// In order for the SDK to process touch events properly, user interaction
// should be disabled.
adView.callToActionView?.isUserInteractionEnabled = false
return nativeAdCell
}
}
// MARK: - ViewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
// // Google Admob
let options = GADMultipleAdsAdLoaderOptions()
options.numberOfAds = numAdsToLoad
// Prepare the ad loader and start loading ads.
adLoader = GADAdLoader(adUnitID: adUnitID,
rootViewController: self,
adTypes: [.unifiedNative],
options: [options])
collectionView.dataSource = self
collectionView.delegate = self
adLoader.delegate = self
adLoader.load(GADRequest())
self.collectionView.register(UINib(nibName: "NativeAdCell", bundle: nil), forCellWithReuseIdentifier: "UnifiedNativeAdCell")
addNativeAds()
}
@objc func handleRefresh() {
posts.removeAll(keepingCapacity: false)
self.currentKey = nil
fetchPosts()
collectionView?.reloadData()
header?.profilesCollectionView.reloadData()
}
}
获取Post
func fetchPosts() {
guard let currentUid = Auth.auth().currentUser?.uid else { return }
if currentKey == nil {
USER_FEED_REF.child(currentUid).queryLimited(toLast: 5).observeSingleEvent(of: .value, with: { (snapshot) in
self.collectionView?.refreshControl?.endRefreshing()
guard let first = snapshot.children.allObjects.first as? DataSnapshot else { return }
guard let allObjects = snapshot.children.allObjects as? [DataSnapshot] else { return }
allObjects.forEach({ (snapshot) in
let postId = snapshot.key
self.fetchPost(withPostId: postId)
})
self.currentKey = first.key
})
} else {
USER_FEED_REF.child(currentUid).queryOrderedByKey().queryEnding(atValue: self.currentKey).queryLimited(toLast: 6).observeSingleEvent(of: .value, with: { (snapshot) in
guard let first = snapshot.children.allObjects.first as? DataSnapshot else { return }
guard let allObjects = snapshot.children.allObjects as? [DataSnapshot] else { return }
allObjects.forEach({ (snapshot) in
let postId = snapshot.key
if postId != self.currentKey {
self.fetchPost(withPostId: postId)
}
})
self.currentKey = first.key
})
}
}
func fetchPost(withPostId postId: String) {
Database.fetchPost(with: postId) { (post) in
self.posts.append(post)
self.posts.sort(by: { (post1, post2) -> Bool in
return post1.creationDate > post2.creationDate
})
self.collectionView?.reloadData()
}
}
}
您的 FollowingFeedViewController
不是 UICollectionViewController
的子类,对吧?因此,您应该设置 collectionView 实例的 delegate 和 dataSource 属性。
大概是这样的:
override func viewDidLoad() {
super.viewDidLoad()
collectionView.delegate = self
collectionView.dataSource = self
}
看起来至少您的部分代码丢失了。我看不到 fetchPosts 方法。
我注意到 handleRefresh 在 reloadData 之前调用 fetchPosts。 fetchPosts 是同步加载数据还是异步加载数据?如果是异步加载数据,reloadData会在数据准备好之前调用。
广告也是如此。广告准备就绪后,我看不到对集合视图的任何 reloadData(或等效)调用。如果您 post 您的完整代码,诊断问题会更容易。
我认为这行得通,我从您的代码中可以看出您有两个数据源
var posts = [Post]()
var collectionObject = [AnyObject]()
并且您想为所有这些创建单元格,但是根据您的代码
,您要显示的唯一数据源是 posts
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return posts.count
}
这可以通过将您的代码更改为类似这样的内容来解决
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 2
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if (section == 0) {
return posts.count
} else {
return collectionObject.count
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if (indexPath.section == 0) {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PostsCell", for: indexPath) as FollowingCell
cell.delegate = self
cell.post = posts[indexPath.item] as Post
handleUsernameLabelTapped(forCell: cell)
handleMentionTapped(forCell: cell)
handleHashtagTapped(forCell: cell)
return cell
} else {
let nativeAd = collectionObject[indexPath.row] as! GADUnifiedNativeAd
nativeAd.rootViewController = self
let nativeAdCell = collectionView.dequeueReusableCell(withReuseIdentifier: "UnifiedNativeAdCell", for: indexPath)
// Get the ad view from the Cell. The view hierarchy for this cell is defined in
let adView : GADUnifiedNativeAdView = nativeAdCell.contentView.subviews
.first as! GADUnifiedNativeAdView
// Associate the ad view with the ad object.
// This is required to make the ad clickable.
adView.nativeAd = nativeAd
adView.mediaView?.mediaContent = nativeAd.mediaContent
// Populate the ad view with the ad assets.
(adView.headlineView as! UILabel).text = nativeAd.headline
(adView.advertiserView as! UILabel).text = nativeAd.advertiser
(adView.bodyView as! UILabel).text = nativeAd.body
adView.bodyView?.isHidden = nativeAd.body == nil
(adView.iconView as? UIImageView)?.image = nativeAd.icon?.image
adView.iconView?.isHidden = nativeAd.icon == nil
// In order for the SDK to process touch events properly, user interaction
// should be disabled.
adView.callToActionView?.isUserInteractionEnabled = false
return nativeAdCell
}
}
此代码首先添加帖子,然后开始添加您的添加。
检查一下,让我知道它是否有效。如果这显示单元格,那么您可以将两个数据源混合在一起,并使用条件填充您的集合视图单元格,就像您创建一个新对象,该对象使用当前对象 posts
& collectionObject
if indexPath.item % 4 == 0 {
show adds
} else {
show posts
}
希望这会有所帮助
这是我第一次使用 Google AdMob 原生广告,我相信我遵循了实施说明。剩下的就是在集合视图中实际显示广告,这就是我所在的位置卡住。我不知道如何在上传的用户之间正确显示广告 post。基本上我需要帮助将 xib 添加到集合视图。任务:滚动浏览 posts..
时应填充广告我正在使用
集合视图 西布 Google AdMob 原生高级
我也没有收到任何错误或崩溃,控制台打印,所以我显然做错了什么。收到原生广告:
控制台也 - print
("Ads not dispalying ") 和 print
("Not what I want")
这是我的代码
import UIKit
import Firebase
class FollowingFeedViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UISearchBarDelegate, FeedCellDelegate, PeopleToFollowDelegate, GADUnifiedNativeAdLoaderDelegate {
// MARK: - Google ADMob
/// The ad unit ID from the AdMob UI.
let adUnitID = "ca-app-pub-3940256099942544/3986624511"
/// The number of native ads to load (between 1 and 5 for this example).
let numAdsToLoad = 5
/// The native ads.
var nativeAds = [GADUnifiedNativeAd]()
/// The ad loader that loads the native ads.
var adLoader: GADAdLoader!
func adLoaderDidFinishLoading(_ adLoader: GADAdLoader) {
addNativeAds()
}
func adLoader(_ adLoader: GADAdLoader, didReceive nativeAd: GADUnifiedNativeAd) {
print("Received native ad: \(nativeAd)")
// Add the native ad to the list of native ads.
nativeAds.append(nativeAd)
}
func adLoader(_ adLoader: GADAdLoader, didFailToReceiveAdWithError error: GADRequestError) {
print("\(adLoader) failed with error: \(error.localizedDescription)")
}
/// Add native ads to the list.
func addNativeAds() {
if nativeAds.count <= 0 {
print("Ads not dispalying ")
return
}
let adInterval = (posts.count / nativeAds.count) + 1
var index = 0
for nativeAd in nativeAds {
if index < collectionObject.count {
collectionObject.insert(nativeAd, at: index)
index += adInterval
} else {
print("Not what I want")
break
}
}
}
// MARK: - Properties
var posts = [Post]()
var collectionObject = [AnyObject]()
var viewSinglePost = false
var post: Post?
var currentKey: String?
var userProfileController: ProfileViewController?
var header: FeedReusableView?
@IBOutlet weak var collectionView: UICollectionView!
// MARK: - UICollectionViewDataSource
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if posts.count > 4 {
if indexPath.item == posts.count - 1 {
fetchPosts()
}
}
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return posts.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PostsCell", for: indexPath) as? FollowingCell {
cell.delegate = self
cell.post = posts[indexPath.item] as Post
handleUsernameLabelTapped(forCell: cell)
handleMentionTapped(forCell: cell)
handleHashtagTapped(forCell: cell)
return cell
} else {
let nativeAd = collectionObject[indexPath.row] as! GADUnifiedNativeAd
nativeAd.rootViewController = self
let nativeAdCell = collectionView.dequeueReusableCell(withReuseIdentifier: "UnifiedNativeAdCell", for: indexPath)
// Get the ad view from the Cell. The view hierarchy for this cell is defined in
let adView : GADUnifiedNativeAdView = nativeAdCell.contentView.subviews
.first as! GADUnifiedNativeAdView
// Associate the ad view with the ad object.
// This is required to make the ad clickable.
adView.nativeAd = nativeAd
adView.mediaView?.mediaContent = nativeAd.mediaContent
// Populate the ad view with the ad assets.
(adView.headlineView as! UILabel).text = nativeAd.headline
(adView.advertiserView as! UILabel).text = nativeAd.advertiser
(adView.bodyView as! UILabel).text = nativeAd.body
adView.bodyView?.isHidden = nativeAd.body == nil
(adView.iconView as? UIImageView)?.image = nativeAd.icon?.image
adView.iconView?.isHidden = nativeAd.icon == nil
// In order for the SDK to process touch events properly, user interaction
// should be disabled.
adView.callToActionView?.isUserInteractionEnabled = false
return nativeAdCell
}
}
// MARK: - ViewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
// // Google Admob
let options = GADMultipleAdsAdLoaderOptions()
options.numberOfAds = numAdsToLoad
// Prepare the ad loader and start loading ads.
adLoader = GADAdLoader(adUnitID: adUnitID,
rootViewController: self,
adTypes: [.unifiedNative],
options: [options])
collectionView.dataSource = self
collectionView.delegate = self
adLoader.delegate = self
adLoader.load(GADRequest())
self.collectionView.register(UINib(nibName: "NativeAdCell", bundle: nil), forCellWithReuseIdentifier: "UnifiedNativeAdCell")
addNativeAds()
}
@objc func handleRefresh() {
posts.removeAll(keepingCapacity: false)
self.currentKey = nil
fetchPosts()
collectionView?.reloadData()
header?.profilesCollectionView.reloadData()
}
}
获取Post
func fetchPosts() {
guard let currentUid = Auth.auth().currentUser?.uid else { return }
if currentKey == nil {
USER_FEED_REF.child(currentUid).queryLimited(toLast: 5).observeSingleEvent(of: .value, with: { (snapshot) in
self.collectionView?.refreshControl?.endRefreshing()
guard let first = snapshot.children.allObjects.first as? DataSnapshot else { return }
guard let allObjects = snapshot.children.allObjects as? [DataSnapshot] else { return }
allObjects.forEach({ (snapshot) in
let postId = snapshot.key
self.fetchPost(withPostId: postId)
})
self.currentKey = first.key
})
} else {
USER_FEED_REF.child(currentUid).queryOrderedByKey().queryEnding(atValue: self.currentKey).queryLimited(toLast: 6).observeSingleEvent(of: .value, with: { (snapshot) in
guard let first = snapshot.children.allObjects.first as? DataSnapshot else { return }
guard let allObjects = snapshot.children.allObjects as? [DataSnapshot] else { return }
allObjects.forEach({ (snapshot) in
let postId = snapshot.key
if postId != self.currentKey {
self.fetchPost(withPostId: postId)
}
})
self.currentKey = first.key
})
}
}
func fetchPost(withPostId postId: String) {
Database.fetchPost(with: postId) { (post) in
self.posts.append(post)
self.posts.sort(by: { (post1, post2) -> Bool in
return post1.creationDate > post2.creationDate
})
self.collectionView?.reloadData()
}
}
}
您的 FollowingFeedViewController
不是 UICollectionViewController
的子类,对吧?因此,您应该设置 collectionView 实例的 delegate 和 dataSource 属性。
大概是这样的:
override func viewDidLoad() {
super.viewDidLoad()
collectionView.delegate = self
collectionView.dataSource = self
}
看起来至少您的部分代码丢失了。我看不到 fetchPosts 方法。
我注意到 handleRefresh 在 reloadData 之前调用 fetchPosts。 fetchPosts 是同步加载数据还是异步加载数据?如果是异步加载数据,reloadData会在数据准备好之前调用。
广告也是如此。广告准备就绪后,我看不到对集合视图的任何 reloadData(或等效)调用。如果您 post 您的完整代码,诊断问题会更容易。
我认为这行得通,我从您的代码中可以看出您有两个数据源
var posts = [Post]()
var collectionObject = [AnyObject]()
并且您想为所有这些创建单元格,但是根据您的代码
,您要显示的唯一数据源是posts
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return posts.count
}
这可以通过将您的代码更改为类似这样的内容来解决
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 2
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if (section == 0) {
return posts.count
} else {
return collectionObject.count
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if (indexPath.section == 0) {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PostsCell", for: indexPath) as FollowingCell
cell.delegate = self
cell.post = posts[indexPath.item] as Post
handleUsernameLabelTapped(forCell: cell)
handleMentionTapped(forCell: cell)
handleHashtagTapped(forCell: cell)
return cell
} else {
let nativeAd = collectionObject[indexPath.row] as! GADUnifiedNativeAd
nativeAd.rootViewController = self
let nativeAdCell = collectionView.dequeueReusableCell(withReuseIdentifier: "UnifiedNativeAdCell", for: indexPath)
// Get the ad view from the Cell. The view hierarchy for this cell is defined in
let adView : GADUnifiedNativeAdView = nativeAdCell.contentView.subviews
.first as! GADUnifiedNativeAdView
// Associate the ad view with the ad object.
// This is required to make the ad clickable.
adView.nativeAd = nativeAd
adView.mediaView?.mediaContent = nativeAd.mediaContent
// Populate the ad view with the ad assets.
(adView.headlineView as! UILabel).text = nativeAd.headline
(adView.advertiserView as! UILabel).text = nativeAd.advertiser
(adView.bodyView as! UILabel).text = nativeAd.body
adView.bodyView?.isHidden = nativeAd.body == nil
(adView.iconView as? UIImageView)?.image = nativeAd.icon?.image
adView.iconView?.isHidden = nativeAd.icon == nil
// In order for the SDK to process touch events properly, user interaction
// should be disabled.
adView.callToActionView?.isUserInteractionEnabled = false
return nativeAdCell
}
}
此代码首先添加帖子,然后开始添加您的添加。
检查一下,让我知道它是否有效。如果这显示单元格,那么您可以将两个数据源混合在一起,并使用条件填充您的集合视图单元格,就像您创建一个新对象,该对象使用当前对象 posts
& collectionObject
if indexPath.item % 4 == 0 {
show adds
} else {
show posts
}
希望这会有所帮助