swift - 缓存的图像闪烁

标签 swift firebase uitableview caching firebase-storage

我正在从 Cloud Storage 下载图像,它们会在我的整个应用中使用。我已经缓存了它们,但当我的表格滚动或重新加载时,我仍然看到一些闪烁。

这是我尝试过的:

我的缓存代码:

import UIKit

class ImageService {

    static let cache = NSCache<NSString, UIImage>()

    static func downloadImage(withURL url:URL, completion: @escaping (_ image:UIImage?)->()) {
        let dataTask = URLSession.shared.dataTask(with: url) { data, responseURL, error in
            var downloadedImage: UIImage?

            downloadedImage = nil

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

            if downloadedImage != nil {
                cache.setObject(downloadedImage!, forKey: url.absoluteString as NSString)
            }

            DispatchQueue.main.async {
                completion(downloadedImage)
            }
        }

        dataTask.resume()
    }

    static func getImage(withURL url:URL, completion: @escaping (_ image:UIImage?)->()) {
        if let image = cache.object(forKey: url.absoluteString as NSString) {
            print("IMAGE IS LOADED FROM CACHE!!!!")
            DispatchQueue.main.async {
                completion(image)
            }
        } else {
            print("IMAGE IS LOADED FROM DOWNLOAD!!!!")
            downloadImage(withURL: url, completion: completion)
        }
    }
}

这是我的一个表格中的示例:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    cell.imageView.image = nil

    let storage = Storage.storage()
    let storageRef = storage.reference()
    let imageRef = storageRef.child(String(format: "images/%@.jpg", id))

    imageRef.downloadURL { (URL, error) in
        if error == nil {
            DispatchQueue.main.async {
                ImageService.getImage(withURL: URL!, completion: { image in
                   cell.imageView.image = image
              })
           }
        } else {
          cell.imageView.image = UIImage (named: "placeholder")
        }
    }
}

我看到当我第一次加载我的应用程序时,图像被下载,然后它们从缓存中加载。但我仍然看到它们在闪烁。有什么建议可以更新以上内容以缓存到内存和磁盘或解决闪烁问题吗?

解决方案:

我正在使用 FirebaseUI,它有一个修改版本的 SDWebImage,可以根据存储引用进行缓存。

最佳答案

TBH 我不知道这是否有效。但我有同样的问题,你必须在某个地方将 cell.imageview 设置为 nil

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// cell.imageView.image = nil (remove)

let storage = Storage.storage()
let storageRef = storage.reference()
let imageRef = storageRef.child(String(format: "images/%@.jpg", id))

imageRef.downloadURL { (URL, error) in
    if error == nil {
        DispatchQueue.main.async {

            ImageService.getImage(withURL: URL!, completion: { image in
               cell.imageView.image = nil //add
               cell.imageView.image = image
          })
       }
    } else {
      cell.imageView.image = nil // Add
      cell.imageView.image = UIImage (named: "placeholder")
    }
}
}

关于swift - 缓存的图像闪烁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55094738/

相关文章:

javascript - Firebase:添加新子项

java - 如何将 FCM token ID 发送到 PHP 服务器?

ios - UILabels 阻止自定义 UITableViewCell 上的单元格选择

ios - FBSDKLog : FBSDKGraphRequestConnection cannot be started before Facebook SDK initialized

ios - 复选框在 Swift 中选中的 Action ?

ios - 有人设法在 iOS 上使用 Firebase 实现了 LinkedIn 登录吗?

ios - 如何快速显示来自嵌套 firebase 节点的数据?

arrays - 在 Swift 中将 JSON 数组转换为 Int 数组

ios - NSFetchedResultsController 与来自其他模型的数据

swift - 如何在 UITableView 中移动行后更新 CoreData?