Problem:
我需要顶部填充tableView 以保持现有单元格的内容加载,例如播放视频。
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)
})
上述方法的问题在于,在分配标签时,单元格索引路径都是相同的
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:
单元格索引路径:[0, 0] 单元格索引路径:[0, 0] 单元格索引路径:
[0, 0] 单元格索引路径:[0, 0] 单元格索引路径:[0, 0] 单元格索引
路径: [0, 0] 单元格索引路径: [0, 0] 单元格索引路径: [0, 0]
正确的方法是什么top loadtableView 通过使用 insertRows 但维护唯一的 indexPath.row 值?
tableView.reloadData() 为我提供了正确的唯一索引,但没有提供顶部加载 tableView 以避免单元格数据刷新(例如在单元格中播放视频)的能力。
伪代码:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
customCounter = customCounter + 1
let cellTag = customCounter
print("cell index tag: ", cellTag)
}
我也尝试过 self.posts.count - 1,但索引在初始加载时未正确显示。当我滚动到底部然后回到顶部时,它们已正确就位。
self.tableView.insertRows(at: [IndexPath.init(row: self.posts.count - 1, section: 0)], with: .automatic)