正如我的标题所述,当我滚动浏览表格视图时,我的tableView中的图片会移动并且不会显示在正确的帖子上。在我停止滚动后,它们似乎又回到原位。
我一直试图从以下文章中理解:
new Firebase retrieve data and put on the tableview swift
retrieve image from Firebase storage to show on tableview swift
swift Firebase sort posts in tableview by date
但我无法弄清楚如何让图片更好地显示。 这就是我所拥有的:
import UIKit
import FirebaseAuth
import FirebaseDatabase
import FirebaseStorage
class MainFeedTableViewController: UITableViewController {
var posts = [Post]()
let alert = AlertsViewController()
var databaseRef: FIRDatabaseReference! {
return FIRDatabase.database().reference()
}
var storageRef: FIRStorage! {
return FIRStorage.storage()
}
override func viewDidLoad() {
super.viewDidLoad()
fetchPosts()
}
// populates the tableView with posts content in real time
private func fetchPosts(){
let postRefs = databaseRef.child("posts")
postRefs.observe(.value) { (snapshot: FIRDataSnapshot) in
var newPost = [Post]()
for post in snapshot.children{
let postObject = Post(snapshot: post as! FIRDataSnapshot)
newPost.insert(postObject, at: 0)
}
self.posts = newPost
self.tableView.reloadData()
}
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let postsAtIndexPath = posts[indexPath.row]
if postsAtIndexPath.postWithImage == true {
let cell = tableView.dequeueReusableCell(withIdentifier: "postWithImage", for: indexPath) as! PostWithImageTableViewCell
let postUser = postsAtIndexPath.uid
let userRef = databaseRef.child("users/\(postUser!)")
userRef.observe(.value, with: { (snapshot) in
let user = User(snapshot: snapshot)
DispatchQueue.main.async(execute: {
cell.userRealNameLabel.text = user.name
cell.usernameLabel.text = "@" + user.username
cell.postTextView.text = postsAtIndexPath.postText
cell.timeStampLabel.text = postsAtIndexPath.date
})
self.storageRef.reference(forURL: user.photoURL).data(withMaxSize: 1 * 1024 * 1024, completion: { (data, error) in
if error == nil{
DispatchQueue.main.async(execute: {
if let data = data{
cell.userProfilePicture.image = UIImage(data: data)
}
})
}
else{
print(error!.localizedDescription)
}
})
self.storageRef.reference(forURL: postsAtIndexPath.postPictureURL).data(withMaxSize: 1 * 1024 * 1024, completion: { (data, error) in
if error == nil{
DispatchQueue.main.async(execute: {
if let data = data{
cell.postImage.image = UIImage(data: data)
}
})
}
else{
self.alert.displayAlert(alertTitle: "Error", alertMessage: error!.localizedDescription, fromController: self)
}
})
}) { (error) in
self.alert.displayAlert(alertTitle: "Error", alertMessage: error.localizedDescription, fromController: self)
}
return cell
}
else{
let cell = tableView.dequeueReusableCell(withIdentifier: "postWithText", for: indexPath) as! PostTableViewCell
let postUser = postsAtIndexPath.uid
let userRef = databaseRef.child("users/\(postUser!)")
userRef.observe(.value, with: { (snapshot) in
let user = User(snapshot: snapshot)
DispatchQueue.main.async(execute: {
cell.userRealNameLabel.text = user.name
cell.usernameLabel.text = "@" + user.username
cell.postTextView.text = postsAtIndexPath.postText
cell.timestampLabel.text = postsAtIndexPath.date
})
self.storageRef.reference(forURL: user.photoURL).data(withMaxSize: 1 * 1024 * 1024, completion: { (data, error) in
if error == nil{
DispatchQueue.main.async(execute: {
if let data = data{
cell.userProfilePicture.image = UIImage(data: data)
}
})
}
else{
print(error!.localizedDescription)
}
})
}) { (error) in
self.alert.displayAlert(alertTitle: "Error", alertMessage: error.localizedDescription, fromController: self)
}
return cell
}
}
}
我之所以遇到困难,是因为我希望用户的用户名,姓名和个人资料图片能够在编辑信息时随时随地进行更改。这就是我根据帖子的用户uid检索用户信息的原因。
实施此更好的方法是什么?
答案 0 :(得分:3)
您必须覆盖prepareForReuse
中的PostWithImageTableViewCell
功能。
示例强>
override func prepareForReuse() {
super.prepareForReuse()
self.userProfilePicture.image = nil
//reset the rest of the values on your `UITableViewCell` subclass
}
修改强>
由于重用问题已经解决,我建议使用以下缓存框架Kingfisher,以获得更方便的图像显示体验。
Kingfisher在UIImageView
上有一个很好的扩展,会为你的缓存提供什么。
在这里你将如何使用它:
let url = URL(string: "https://domain.com/image.jpg")!
imageView.kf.setImage(with: url)
您只需设置为URL,唯一标识图像资源的内容,并且只下载一次。这是一个cheat sheet,如何使用它。