2017-06-06 6 views
1

をダウンロードしてください。これは私の問題です:URLから画像を非同期でダウンロードしますが、TableViewをすばやくスクロールすると画像が回転し始めます(正しい画像が表示されるまで画像が交互に表示されます)。スウィフト画像私はスウィフトでテーブルビューで非同期に画像をダウンロードして問題を解決しようとしているテーブルビュー

これは私のダウンロード非同期コードとのImageCache

let imageCache = NSCache() 

//DOWNLOAD Image ASINC 
extension UIImageView { 

    public func imageFromServerURL(url: String){ 

     if(imageCache.objectForKey(url) != nil){ 
      self.image = imageCache.objectForKey(url) as? UIImage 
     }else{ 

      let sessionConfig = NSURLSessionConfiguration.defaultSessionConfiguration() 
      let session = NSURLSession(configuration: sessionConfig, delegate: nil, delegateQueue: nil) 
      let task = session.dataTaskWithURL(NSURL(string: url)!, completionHandler: { (data, response, error) -> Void in 
       if error == nil { 

        dispatch_async(dispatch_get_main_queue(), {() -> Void in 
         if let downloadedImage = UIImage(data: data!) { 
          imageCache.setObject(downloadedImage, forKey: url) 
          self.image = downloadedImage 
         } 
        }) 

       } 
       else { 
        print(error) 
       } 
      }) 
      task.resume() 
     } 

    } 
} 

と私はテーブルビューでリコールです:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 

     let cell = tableView.dequeueReusableCellWithIdentifier("record_charts", forIndexPath: indexPath) as! myTableViewCell 

      let url_img = "https://image/download.jpg" 
      cell.immagine.imageFromServerURL(url_img) 


     return cell 
    } 

これは Gif Problem

+0

チェックこの質問:https://stackoverflow.com/questions/15668160/asynchronous-downloading-of-images-for-uitableview-with-gcd。 –

+0

あなたはあなたの問題は、その質問からある場所の一般的なアイデアを得ることができ – mfiore

+0

...これは、オブジェクト-Cであり、それは動作しません。 –

答えて

1

のようにあなたが要求をキャンセルすることができますiOSのテーブルビューの再利用メカニズム。

class AsyncImageView: UIImageView { 

private var currentUrl: String? //Get a hold of the latest request url 

public func imageFromServerURL(url: String){ 
    currentUrl = url 
    if(imageCache.objectForKey(url) != nil){ 
     self.image = imageCache.objectForKey(url) as? UIImage 
    }else{ 

     let sessionConfig = NSURLSessionConfiguration.defaultSessionConfiguration() 
     let session = NSURLSession(configuration: sessionConfig, delegate: nil, delegateQueue: nil) 
     let task = session.dataTaskWithURL(NSURL(string: url)!, completionHandler: { (data, response, error) -> Void in 
      if error == nil { 

       dispatch_async(dispatch_get_main_queue(), {() -> Void in 
        if let downloadedImage = UIImage(data: data!) { 
         if (url == currentUrl) {//Only cache and set the image view when the downloaded image is the one from last request 
          imageCache.setObject(downloadedImage, forKey: url) 
          self.image = downloadedImage 
         } 

        } 
       }) 

      } 
      else { 
       print(error) 
      } 
     }) 
     task.resume() 
    } 

} 
} 

ノート#1:私はホワイトボードコードの構文が正しいかどうかわから修正をコーディング、そうされなかった あなたはこの問題を解決するために、あなたのコードにいくつかの変更を行うことができます。

ノート#2:代わりにUIImageViewの新しいサブクラスを宣言する、あなたが関連するオブジェクトを使用することができます。

ノート#3:私は強くあなたがAlamoFireImageを使用することをお勧めは、それはまさにあなたが(余りにおよび将来の場合)この場合には必要なものであるUIImageViewのカテゴリがあります。

1
より良いあなたの問題を表示するGIFです

これはセルの再利用によるものです。私は説明しようとします。異なるイメージ(イメージ1〜10)を持つ10個のセルがあるが、5個のセルしか画面に収まらないと仮定します。テーブルがロードを開始し、第1のセルリクエスト画像1は、画像ビューに入れされると、それはバックグラウンドで起こって開始しかしテーブルは、背景画像終了のローディング及び第一セルは画面のスクロールされる前にスクロールされます。今、そのセルはのは、画像1用の画像6.あなたの背景要求は、その後終了し、それは静止画表示に置かれた細胞画像1への参照を保持しているよう要請する第六セルで言わせて再利用されます。その後、イメージ6のバックグラウンドプロセスが終了し、イメージが新しいバージョンに置き換えられます。イメージ6がイメージ1の前に読み込まれてイメージ6がセルに入れられ、イメージ1に置き換えられると、さらに悪化します。

あなたがする必要があるのは、イメージが利用可能であることを確認することができます。私はImageViewの拡張機能を作ることができるとは思っていないので、何らかの種類の中央画像プロバイダなどが必要になるでしょう。

0

あなたはUIImageView延長でキャンセル方法を追加し、それを呼び出すかtableView(_:willDisplay:forRowAt:)またはUITableViewCell

prepareForReuse()にする必要があるか、これがためですSDWebImageのWebキャッシュ

関連する問題