2016-12-19 5 views
0

Я использую Firebase, чтобы загрузить мои изображения в ячейку ImageView моей камеры! существует проблема. Я использую механизм кеширования для предотвращения загрузки изображений при загрузке reusable cells, но изображения не загружаются, пока я не прокрутил свой TableView.TableView Изображения не загружаются, пока не прокрутите

Вот код;

 public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 

    let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! TableViewCell 
    cell.imgv.image = nil 

if let urlString = self.filteredFlats[indexPath.row].flatThumbnailImage?.imageDownloadURL 
    { 
     imageURLString = urlString 

     let url = URL(string: urlString) 
     if let imagefromCache = imageCache.object(forKey: urlString as AnyObject) as? UIImage 
     { 
      DispatchQueue.main.async { 
       cell.imgv.image = imagefromCache 
       return 
      } 
     } 
     else 
     { 

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

        let imagetoCache = UIImage(data:data!) 

        if self.imageURLString == urlString 
        { 
         cell.imgv.image = imagetoCache 

        } 
        self.imageCache.setObject(imagetoCache!, forKey: urlString as AnyObject) 

       } 
      }).resume() 
     } 
    } 
    return cell 
} 

Я думаю, что проблема, когда URLSession скачал изображение и установить его в ImageView, но загруженный образ не не отображается до indexpath.row перезвонил при прокрутке вверх и вниз.

Я понял, что причиной этого является это утверждение if;

if self.imageURLString == urlString 

Но если я удалю его, ячейки будут хуже, чем поведение многоразовой ячейки. Некоторые ячейки все еще показывают старые кешированные изображения.

Действительно не знает, что происходит. Не ожидал, что TableViews - это сложная структура, какая она есть.

Спасибо.

+0

создать расширение ImageView используя этот URL: http://stackoverflow.com/a/37019507/3400991 надеюсь, что он поможет вам –

ответ

0

Я предполагаю, что imageURLString - это поле вашего класса (возможно, UIViewController). Это означает, что imageURLString = urlString изменит свое значение каждый раз, когда вы войдете в свой метод.

Когда таблица визуализируется, она будет вызывать метод для каждой ячейки, каждый раз при запуске загрузки, если требуемое изображение отсутствует в кеше. Но после этих вызовов значение imageURLString будет URL, используемым для последней ячейки, поэтому только эта ячейка фактически будет использовать загруженное изображение.

Если вы хотите, чтобы исправить свой код, вы должны иметь один imageURLString на клетку, например, путем перемещения поля к классу клеток (создать UITableViewCell подкласс в данном случае), и заменить imageURLString и self.imageURLString по cell.imageURLString

0

Я считаю, что imageCache должен быть глобальным и не должен помещаться внутри tableView (_: cellForRowAt :).

Вместо этого перетащите все в пользовательский класс UIImageView, за исключением var imageCache = String: UIImage. Оставьте это глобальным.

Измените все UIImageView, которые будут использовать функцию loadImage (urlString: String), которая находится внутри этого класса CustomImageView, в CustomImageView !.

Пример:

@IBOutlet слабый вар userImage: UIImageView!

изменение

@IBOutlet слабый вар 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) 
0

решаю его следующим способом, который узнал из учебника IOS на YouTube. Мы можем создать класс CustomImageView и let imageCache = NSCache<AnyObject, AnyObject>(), чтобы сохранить изображение Cache.When прокрутка tableview, если есть imageCache для imageView, мы используем его напрямую. Но если он не exsit, мы загрузим изображение с изображением URL-строку и сохраните ее.

import UIKit 

let imageCache = NSCache<AnyObject, AnyObject>() 

class CustomImageView: UIImageView { 

    var imageUrlString :String? 

    func loadImageWithString(_ urlString:String){ 

     imageUrlString = urlString 

     let request = URLRequest(url: URL(string:urlString)!) 

     self.image = nil 

     //imageCache exist,and use it directly 
     if let imageFromCache = imageCache.object(forKey: urlString as AnyObject) as? UIImage { 

      self.image = imageFromCache 
     } 

     //imageCache doesn't exist,then download the image and save it 
     URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in 

      guard let data = data, error == nil else { 
       print(error?.localizedDescription as Any) 
       return 
      } 

      DispatchQueue.main.async() { 

       let imageToCache = UIImage(data: data) 

       imageCache.setObject(imageToCache!, forKey: urlString as String as AnyObject) 

       if self.imageUrlString == urlString{ 

        self.image = imageToCache 
       } 
      } 

     }).resume() 

    } 

} 

И в пользовательском файле ячейки класса, мы можем использовать его следующим образом:

if let imageUrlString = thumbnailUrlString { 
       thumbnailImageView.loadImageWithString(imageUrlString) 
      } 

Обратите внимание, что 1, thumbnailImageView: CustomImageView 2, thumbnailUrlString является необязательным

Смежные вопросы