Problem:
I need to top populate the tableView in order to keep the content of existing cells loaded such as playing a video.
ref.child(live_mode).queryOrderedByKey().queryLimited(toLast: 200).observe(.childAdded, with: {snapshot in
self.posts.insert(PostFeed(uid: uid , profile_image_url: profile_image_url, profile_name: profile_name, post_id: post_id, post_title: post_title, post_text: post_text, post_type: post_type, youtube_video_url: youtube_video_url, youtube_video_id: youtube_video_id, youtube_image_url: youtube_image_url, time_stamp: time_stamp, like_count: "0"), at: 0)
self.tableView.insertRows(at: [IndexPath.init(row: 0, section: 0)], with: .automatic)
})
The problem with the above method is that the cell index paths are all the same when assigning tags in
extension ChatViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if(posts[indexPath.row].post_type == "text"){
let textCell = tableView.dequeueReusableCell(withIdentifier: "TextTableViewCell", for: indexPath) as! TextTableViewCell
textCell.mainContentView.backgroundColor = .appBackgroundColor
let profileImageURL = posts[indexPath.row].profile_image_url
textCell.profileImageView.layer.borderWidth = 1.0
textCell.profileImageView.layer.masksToBounds = false
textCell.profileImageView.layer.borderColor = UIColor.white.cgColor
textCell.profileImageView.layer.cornerRadius = textCell.profileImageView.frame.size.width / 2
textCell.profileImageView.clipsToBounds = true
textCell.profileImageView.af_setImage(withURL: URL(string: profileImageURL)!, placeholderImage: avatar_placeholder, filter: nil, imageTransition: .crossDissolve(0.5), runImageTransitionIfCached: true, completion: nil)
textCell.usernameLabel.text = posts[indexPath.row].profile_name
textCell.textBodyTextView.text = posts[indexPath.row].post_text
textCell.usernameLabel.font = .sfProMedium(ofSize: 14)
textCell.usernameLabel.textColor = .systemGray
textCell.textBodyTextView.font = .sfProSemiBold(ofSize: 15)
textCell.textBodyTextView.textColor = .label
textCell.shareButton.addTarget(self, action: #selector(shareButtonTap(sender:)), for: .touchUpInside)
textCell.shareButton.tag = indexPath.row
textCell.elipsesButton.addTarget(self, action: #selector(elipsesButtonTap(sender:)), for: .touchUpInside)
textCell.elipsesButton.tag = indexPath.row
return textCell
}else{
print("print loadign cll: ", indexPath.row)
let videoCell = tableView.dequeueReusableCell(withIdentifier: "VideoTableViewCell", for: indexPath) as! VideoTableViewCell
videoCell.mainContentView.backgroundColor = .appBackgroundColor
let profileImageURL = posts[indexPath.row].profile_image_url
let youtubeImageURL = posts[indexPath.row].youtube_image_url
let yt_video_id = posts[indexPath.row].youtube_video_id
videoCell.profileImageView.layer.borderWidth = 1.0
videoCell.profileImageView.layer.masksToBounds = false
videoCell.profileImageView.layer.borderColor = UIColor.white.cgColor
videoCell.profileImageView.layer.cornerRadius = videoCell.profileImageView.frame.size.width / 2
videoCell.profileImageView.clipsToBounds = true
videoCell.usernameLabel.text = posts[indexPath.row].profile_name
videoCell.textBodyTextView.text = posts[indexPath.row].post_title
videoCell.usernameLabel.font = .sfProMedium(ofSize: 14)
videoCell.usernameLabel.textColor = .systemGray
videoCell.textBodyTextView.font = .sfProSemiBold(ofSize: 15)
videoCell.textBodyTextView.textColor = .label
videoCell.yt_thumbnail_image.isHidden = false
let recognizer = UITapGestureRecognizer(target: self, action: #selector(handleYTTap(_:)))
videoCell.yt_thumbnail_image.tag = indexPath.row
videoCell.yt_thumbnail_image.isUserInteractionEnabled = true
videoCell.yt_thumbnail_image.addGestureRecognizer(recognizer)
recognizer.delegate = self
recognizer.view?.tag = indexPath.row
videoCell.shareButton.addTarget(self, action: #selector(shareButtonTap(sender:)), for: .touchUpInside)
videoCell.shareButton.tag = indexPath.row
videoCell.elipsesButton.addTarget(self, action: #selector(elipsesButtonTap(sender:)), for: .touchUpInside)
videoCell.elipsesButton.tag = indexPath.row
videoCell.elipsesButton.isUserInteractionEnabled = true
videoCell.logoLoadingImageView.isHidden = true
videoCell.playerView.isHidden = true
videoCell.playerView.delegate = self
videoCell.playerView.tag = indexPath.row
videoCell.profileImageView.af_setImage(withURL: URL(string: profileImageURL)!, placeholderImage: avatar_placeholder, filter: nil, imageTransition: .crossDissolve(0.5), runImageTransitionIfCached: true, completion: nil)
videoCell.yt_thumbnail_image.af_setImage(withURL: URL(string: youtubeImageURL)!, placeholderImage: thumbnail_placeholder, filter: nil, imageTransition: .crossDissolve(0.5), runImageTransitionIfCached: false, completion: nil)
return videoCell
}
return UITableViewCell()
}
OUTPUT:
cell index path: [0, 0] cell index path: [0, 0] cell index path: [0, 0] cell index path: [0, 0] cell index path: [0, 0] cell index path: [0, 0] cell index path: [0, 0] cell index path: [0, 0]
What is the proper way to top load the tableView by using insertRows but maintaining the unique indexPath.row value?
tableView.reloadData() gives me the proper unique index's but doesnt give the ability to top load the tableView to avoid cell data refreshing such as playing a video in the cell.
Pseudocode:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
customCounter = customCounter + 1
let cellTag = customCounter
print("cell index tag: ", cellTag)
}
I have also tried self.posts.count - 1, but indexes are not shown properly on initial load. When i scroll to the bottom then back to the top they are properly in place.
self.tableView.insertRows(at: [IndexPath.init(row: self.posts.count - 1, section: 0)], with: .automatic)