2016-12-19 6 views
0

Firebase을 사용하여 이미지를 내 셀 ImageView에로드하지만! 문제가있다. reusable cells로드 할 때 이미지를 redownload 방지하기 위해 캐싱 메커니즘을 사용하고 있지만 내 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

는 이미지 뷰의 확장을 만들려면 다음과 같이

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() } } 

그리고 사용자 정의 셀 클래스 파일에

, 우리는 그것을 사용할 수 있습니다 이 URL을 사용하여 : http://stackoverflow.com/a/37019507/3400991 당신을 도울 희망 –

답변

0

imageURLString이 클래스 필드 (UIViewController 일 가능성이 있음)를 추측하고 있습니다. 즉, imageURLString = urlString은 귀하가 귀하의 방법을 이용할 때마다 그 값이 변경 될 것입니다.

테이블이 렌더링 될 때마다 필요한 이미지가 캐시에없는 경우 다운로드를 트리거 할 때마다 각 셀에 대해 메소드가 호출됩니다. 그러나 이러한 호출 후에 imageURLString 값은 마지막 셀에 사용 된 URL이 될 것이므로이 셀만 실제로로드 된 이미지를 사용하게됩니다.

당신은 당신의 코드를 수정하려는 경우, 당신은 셀 클래스에 필드를 이동하여 (예를 들어,이 경우에는 UITableViewCell 서브 클래스를 만들 수), 셀 당 하나의 imageURLString 있고, cell.imageURLString

0
에 의해 imageURLStringself.imageURLString을 교체해야합니다

imageCache가 전역이어야하며 내부에 tableView (_ : cellForRowAt :)를 삽입해서는 안됩니다.

대신 var imageCache = String : UIImage를 제외한 모든 사용자 지정 UIImageView 클래스를 처리하십시오. 그 세계를 떠나라.

이 CustomImageView 클래스 내부에있는 loadImage (urlString : String) 함수를 CustomImageView!로 사용할 모든 UIImageView를 변경하십시오.

예 :

@IBOutlet 약한 var에 userImage : UIImageView에!

변화

@IBOutlet 약한 var에 userImage : CustomImageView!load 메소드를 호출

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

내가 YouTube에서 아이폰 OS 튜토리얼에서 배운 다음과 같은 방법으로 해결. CustomImageView 클래스를 만들고 let imageCache = NSCache<AnyObject, AnyObject>() 이미지 캐시를 저장할 수 있습니다. tableview를 스크롤 할 때 imageView에 imageCache가 있으면 직접 사용합니다. 그러나 exsit가 아닌 경우 이미지와 함께 이미지를 다운로드합니다. URL 문자열을 저장하십시오.

은 1, thumbnailImageView이
if let imageUrlString = thumbnailUrlString { 
       thumbnailImageView.loadImageWithString(imageUrlString) 
      } 

하는 것으로 : CustomImageView 2, thumbnailUrlString는 선택 사항입니다