2017-05-05 59 views
3

我已經閱讀過類似文章Reusable cell old image showing,我仍然遇到同樣的問題。從本質上講,我有一個TableView從亞馬遜S3下載圖像,當你向下滾動時,一切正常,直到你看到第12或第13張圖像。會發生什麼情況是,新圖像正在被下載時,該行中的圖像在新行中出現約2秒。這是我的代碼(我還是新手,學習IOS)。 stream_image_string作爲完整的URL下載圖像和PicHeight是一個整數與圖像高度保存,因爲每個圖像通常有不同的高度。IOS tableview在下載新映像時重新使用舊映像問題

var Stream_Cache = NSCache<AnyObject, AnyObject>() 
    var stream_image_string = [String]() 
    var PicHeight = [Int]() 

這下面是在UITableViewCell中,首先我檢查是否有一個url將包含超過0個字符。然後我檢查圖像/ URL是否保存在緩存中,如果沒有,我下載它。

  if stream_image_string[indexPath.row].characters.count > 0 { 
     if let image = Stream_Cache.object(forKey: stream_image_string[indexPath.row] as AnyObject) as? UIImage { 
       DispatchQueue.main.async(execute: {() -> Void in 
      cell.stream_image.image = image 


      }) 
     } else { 
      if cell.stream_image != nil { 
      let strCellImageURL = self.stream_image_string[indexPath.row] 
      let imgURL: NSURL = NSURL(string: strCellImageURL)! 
     let request:NSURLRequest = NSURLRequest(url: imgURL as URL) 
     let config = URLSessionConfiguration.default 
     let session = URLSession(configuration: config) 

     cell.Stream_Image_Height.constant = CGFloat(Float(cell.pic_height!)) 
     let task = session.dataTask(with: request as URLRequest, completionHandler: {(data, response, error) in 
      DispatchQueue.main.async(execute: {() -> Void in 

       if data != nil { 
       cell.stream_image.image = UIImage(data: data!) 
       } else { 
        cell.Stream_Image_Height.constant = 0 
        cell.stream_image.image = nil 
       } 


      }) 
     }); 

     task.resume() 
      } 
    } 
    } else { 

     cell.Stream_Image_Height.constant = 0 
    } 

在我的UITableViewCell文件I圖像設置的情況下,它沒有這樣做加載新圖像的默認圖像,但並未奏效

class HomePageTVC: UITableViewCell { 

    @IBOutlet weak var stream_image: UIImageView! 

    var pic_height: Int? 




    override func awakeFromNib() { 
     super.awakeFromNib() 
     stream_image.image = #imageLiteral(resourceName: "defaultImage") 


    } 

    override func setSelected(_ selected: Bool, animated: Bool) { 
     super.setSelected(selected, animated: animated) 

     // Configure the view for the selected state 
    } 

} 

任何建議將是巨大

回答

4

你正面臨着一個非常常見的單元重用問題。當您將以前使用的單元出列時,它可能已經在其圖像視圖中安裝了一個圖像。開始一個異步下載之前設置圖像爲nil:

if let imageString = stream_image_string[indexPath.row].characters, 
     !imageString.isEmpty { 
    if let image = Stream_Cache.object(forKey: imageString) as? UIImage { 
     cell.stream_image.image = image 
    } else { 
     //Clear out any old image left in the recycled image view. 
     cell.stream_image.image = nil 
     //Your code to download the image goes here 
    } 
    } 

注意,沒有必要來包裝cell.stream_image.image = image代碼中調用DispatchQueue.main.async()。該代碼將在主線程上運行。

,但是,需要圍繞dataTask的completionHandler裏面的代碼的第二DispatchQueue.main.async()包裝,因爲URLSession的完成左撇子被稱爲在默認情況下,後臺排隊。

+0

完美謝謝,這是我需要的 – user1591668