Swift 3:tableView 从 Firebase 复制加载的图像

sno*_*ker 1 uitableview ios firebase swift

我正在尝试显示带有图像的用户列表。这是代码

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! UserListTableViewCell
    let message = messages[indexPath.row]
    cell.message = message
    return cell
}
Run Code Online (Sandbox Code Playgroud)

在 UserListTableViewCell 文件中,我正在下载图像(也使用缓存)并将其显示在表格上。但我看到某些行有重复/重复的图像。重新加载后,重复项消失,但回到垂直滚动状态。

有时候是这样的 : 在此处输入图片说明

这是 UserListTableViewCell 文件:

import UIKit
import Firebase

class UserListTableViewCell: UITableViewCell {

@IBOutlet weak var username: UILabel!
@IBOutlet weak var textMessage: UILabel!
@IBOutlet weak var timeLabel: UILabel!
@IBOutlet weak var userImage: UIImageView!



var message: Message? {

    didSet {

        if let id = message?.chatPartnerID() {

            let database = Database.database().reference()
            let ref = database.child("Users").child(id)
            ref.observeSingleEvent(of: .value, with: {
                (snapshot) in

                if let dictionary = snapshot.value as? [String: AnyObject] {


                        self.username.text = dictionary["username"] as? String

                        if let profileImageUrl = dictionary["image"] as? String, profileImageUrl != "" {
                                                            self.userImage.image = UIImage(named: "blank-user")
                            self.userImage.loadImageFromCacheWithUrlString(urlString: profileImageUrl)
                            self.userImage.layer.cornerRadius = self.userImage.frame.size.width/2
                            self.userImage.clipsToBounds = true

                        } else {

                            self.userImage.image = UIImage(named: "blank-user")
                            self.userImage.layer.cornerRadius = self.userImage.frame.size.width/2
                            self.userImage.clipsToBounds = true
                        }

                }



            }, withCancel: nil)
        }


        textMessage.text = (message?.text)! + " " + (message?.chatPartnerID())!

        if let seconds = message?.timestamp?.doubleValue {
            let timestampDate = Date(timeIntervalSince1970: seconds)

            let dateFormatter = DateFormatter()
            dateFormatter.dateFormat = "hh:mm a"
            timeLabel.text = dateFormatter.string(from: timestampDate)
        }


        //userImage.image = message?.
    }
} }
Run Code Online (Sandbox Code Playgroud)

图片下载扩展文件:

extension UIImageView {
func loadImageFromCacheWithUrlString( urlString: String) {

    if urlString != "" {
        self.image = nil

        if let cachedImage = imageCache.object(forKey: urlString as AnyObject) {

            self.image = cachedImage as? UIImage
            self.contentMode = .scaleAspectFill
            return
        }


        let url = URL(string : urlString )

        URLSession.shared.dataTask(with: url!, completionHandler: { (data, response, error) in

            if error != nil {
                print(error!)
                return
            }

            DispatchQueue.main.async(execute: {

                if let downloadedImage = UIImage(data: data!) {

                    imageCache.setObject(downloadedImage, forKey: urlString as AnyObject)
                    self.image = downloadedImage
                    self.contentMode = .scaleAspectFill
                }


            })

        }).resume()
    }


}
Run Code Online (Sandbox Code Playgroud)

}

Naz*_*san 5

基本上,您使用单元格重用,因此每次新重用前一个单元格时,都是重用先前的单元格数据,因此您需要清除以前的数据。您应该 nil 图像查看下载新图像或使用占位符图像

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! UserListTableViewCell
    .   cell.userImage.image = nil
        let message = messages[indexPath.row]
        cell.message = message
        return cell
}
Run Code Online (Sandbox Code Playgroud)

更新: 来自苹果文档

如果 UITableViewCell 对象是可重用的——也就是说,它有一个重用标识符——这个方法会在对象从 UITableView 方法 dequeueReusableCell(withIdentifier:) 返回之前调用。出于性能原因,您应该只重置与内容无关的单元格属性,例如 alpha、编辑和选择状态。tableView(_:cellForRowAt:) 中表格视图的委托在重用单元格时应始终重置所有内容。如果单元格对象没有关联的重用标识符,则不会调用此方法。如果覆盖此方法,则必须确保调用超类实现。

所以放在你的UserListTableViewCell班级

override func prepareForReuse() {
    super.prepareForReuse()
       self.userImage.image() = nil
    // self.userImage.image = nil // above line not working then try this 
}
Run Code Online (Sandbox Code Playgroud)