2017-05-05 4 views
3

私はReusable cell old image showingに似た記事を読みましたが、私はまだ同じ問題を抱えています。本質的には、私はあなたが約12または13番目の画像になるまで、すべてをうまくスクロールするようにamazon s3から画像をダウンロードするTableViewを持っています。何が起こるかは、新しい画像がダウンロードされている間、前の行の画像が新しい行に約2秒間表示されるということです。これは私のコードです(私はIOSの素早い学習ではまだ新しいです)。 ストリーム画像の文字列は、画像をダウンロードするための完全なURLです。PicHeightは、通常、すべての画像の高さが異なるため、画像の高さとともに保存される整数です。IOS tableview新しいイメージをダウンロード中に古いイメージを再利用する問題

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

下記これは最初、私はそれが0以上の文字が含まれています、URLがあるかどうかを確認、UITableViewCellの内側にあります。私は次に、画像/ URLがキャッシュに保存されていない場合はそれをダウンロードするかどうかを確認します。私のUITableViewCellのファイルで

  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 
    } 

は、私はそれが新しいイメージをロードして行われていなかった場合のデフォルトの画像に画像を設定するが、それは素晴らしいことだ

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

あなたは非常に一般的なセル再利用の問題に直面しています。前に使用したセルをデキューすると、イメージビューにイメージがすでにインストールされている可能性があります。

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

DispatchQueue.main.async()への呼び出しでcell.stream_image.image = imageコードをラップする必要がないこと:非同期のダウンロードを開始する前に、nilに画像を設定します。そのコードはメインスレッド上で実行されます。 URLSessionの完了利きは、デフォルトではバックグラウンドキューに呼ばれているので、あなたがを行う

は、しかし、dataTaskのcompletionHandler内のコードの周りに二DispatchQueue.main.async()ラッパーを必要とします。

+0

完璧なおかげで、私は必要なものがたくさんあります – user1591668

関連する問題