【问题标题】:When pulling images from a Firebase storage the images don’t load until I interact with the tableView by scrolling... SWIFT 3从 Firebase 存储中提取图像时,图像不会加载,直到我通过滚动与 tableView 交互... SWIFT 3
【发布时间】:2017-08-21 11:03:04
【问题描述】:

我在使用 twitter/instagram 之类的新闻提要时遇到问题……

当从 Firebase 存储中提取图像时,图像不会加载,直到我通过滚动与 tableView 交互...我滚动得越多,我可以出现的越多。它有时还会随机显示错误的帖子图像,直到我再滚动一些,最终所有图像都加载完毕,它们都在正确的位置。

这没有任何意义……我所有的逻辑都是正确的,我在从数据库加载图像 url 时使用了 cachedImages。我看过很多视频教程,它们都使用了与我类似的方法,但它们都没有像我这样的错误问题。

对可能出现的问题有什么想法吗?

代码:

var imageCache = [String: UIImage]()

var lastURLUsedToLoadImage: String?

// loading user image  from urls
extension UIImageView {
    
    func loadImage(urlString: String) {
        
        lastURLUsedToLoadImage = urlString
        
        if let cachedImage = imageCache[urlString] {
            self.image = cachedImage
            return
        }
        
        guard let url = URL(string: urlString) else { return }
        
        URLSession.shared.dataTask(with: url) { (data, response, err) in
            if let err = err {
                print("Failed to fetch post image:", err)
                return
            }
            
            if url.absoluteString != lastURLUsedToLoadImage {
                return
            }
            
            guard let imageData = data else { return }
            
            let photoImage = UIImage(data: imageData)
            
            imageCache[url.absoluteString] = photoImage
            
            DispatchQueue.main.async {
                self.image = photoImage
            }
            
            }.resume()
    }
}

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    你应该使用

    tableView.reloadData()
    

    图像下载时。

    【讨论】:

    • 我不确定如何让扩展程序识别 tableView。
    【解决方案2】:

    看起来您的变量 lastURLUsedToLoadImage 是全局的 - 您必须“按单元格”存储该数据,而不是全局存储。

    这不是一件容易的事,我推荐使用图像缓存库,比如这个https://github.com/onevcat/Kingfisher

    使用 Kingfisher 加载图像非常简单,看看这个:

    imageView.kf.setImage(with: URL(string: urlString))
    

    【讨论】:

    • 我想通了。当您询问 var lastURLUsedToLoadImage: String?是一个全局变量......它是,这是不正确的。除了 var imageCache = [String: UIImage]() 之外,我将所有内容都放在了 CustomImageView 类中...我离开了那个全局...一切正常。
    【解决方案3】:

    我想通了。除了 var imageCache = String: UIImage 之外,我将所有内容都放在了自定义 UIImageView 类中。我离开了那个全球。一切正常。

    所以 UIImageView 不是一个扩展,而是它自己的自定义类。

    因此,将所有使用 loadImage(urlString: String) 函数的 UIImageView 更改为 CustomImageView。

    例子:

    @IBOutlet 弱 var userImage: UIImageView!

    改成

    @IBOutlet weak var userImage: CustomImageView!

    import UIKit
    
    // global var
    var imageCache = [String: UIImage]()
    
    class CustomImageView: UIImageView {
    
        var lastURLUsedToLoadImage: String?
    
        func loadImage(urlString: String) {
            lastURLUsedToLoadImage = urlString
    
            self.image = nil
    
            if let cachedImage = imageCache[urlString] {
                self.image = cachedImage
                return
            }
    
            guard let url = URL(string: urlString) else { return }
    
            URLSession.shared.dataTask(with: url) { (data, response, err) in
                if let err = err {
                    print("Failed to fetch post image:", err)
                    return
                }
    
                if url.absoluteString != self.lastURLUsedToLoadImage {
                    return
                }
    
                guard let imageData = data else { return }
    
                let photoImage = UIImage(data: imageData)
    
                imageCache[url.absoluteString] = photoImage
    
                // update the UI
                DispatchQueue.main.async {
                    self.image = photoImage
                }
    
                }.resume()
        }
    }
    

    调用加载方法示例:

    cell.userImage.loadImage(urlString: userImageUrl)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-22
      • 2017-01-14
      • 2017-05-04
      • 1970-01-01
      • 1970-01-01
      • 2020-01-02
      • 1970-01-01
      • 2018-09-11
      相关资源
      最近更新 更多