0

私はそれにUIImageViewを持つUITableViewを持っています。これらのimageViewsでは、私はサーバーから画像をダウンロードして表示しています。問題は、私がUITableViewをスクロールすると、最初に別のセルのイメージを表示し、直後(2-3秒後)にセルのimageViewを適切なイメージに更新するということです。なぜUITableViewCellは前回の値を表示した直後に自己を更新するのですか?

どうすれば修正できますか?

extension UIImageView { 
func getDataFromUrl(url:String, completion: ((data: NSData?) -> Void)) { 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { 
     NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: url)!) { (data, response, error) in 
      completion(data: NSData(data: data!)) 
      }.resume() 
    }) 
} 

func downloadImage(url:String){ 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { 
     self.getDataFromUrl(url) { data in 
      dispatch_async(dispatch_get_main_queue()) { 
       self.contentMode = UIViewContentMode.ScaleAspectFill 
       self.image = UIImage(data: data!) 
      } 
     } 
    }) 
} 
} 

として私のcellForRowAtIndexPathにこれらの拡張機能を使用します:私はそのように、背景とメインスレッドのミックスを使用しようとした

cell.coverImage.downloadImage("\(credentials.postCoverURL)\(recentNews[indexPath.row].image)") 

が、それは私を助けていません。以前と同じように動作します。私は間違っている?可能であれば、答えに説明(説明)をしてください。それはより便利になります!ありがとう!実際にあなたのコード内で何が起こっている

UPDATE

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    let cell: newsCell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! newsCell 
    cell.coverImage.downloadImage("\(credentials.postCoverURL)\(recentNews[indexPath.row].image)") 

    return cell 
} 

答えて

0

は、すべての細胞が、それら全てが同じオブジェクトプールに入れます。つまり、再利用識別子を与えられているということです。つまり、[tableView dequeueReusableCellWithIdentifier:CustomCellIdentifier]を使用すると、この1つのプールからセルを取得していることを確認します。すでに画像を設定しておき、それをクリアする必要があります。

イメージをダウンロードするようにセルを設定する前に、イメージを消去する必要があります。

cell.coverImage.image = nil 
cell.coverImage.downloadImage("\(credentials.postCoverURL)\(recentNews[indexPath.row].image)") 
+0

なし、同じこと –

+0

は、あなたが質問のアップデートでcellForRowAtIndexPath –

+0

一見のコードを貼り付けることができ、してください –

0

問題を説明しましょう。

最初の行があるとします。これをROW_Aオブジェクトといいます。 ROW_AはスレッドTHREAD_1を使用してURL_1の画像をダウンロードして表示する必要があります。 cellForRow関数の場合、THREAD_1を起動してROW_Aのイメージをダウンロードしました

スクロールすると、最初の行が表示されなくなり、ROW_Aビューオブジェクトが別の行(11th行など)を表示するために再利用されます。 cellForRowで、同じプロセスは以前のように、あなたはURL_11で画像をダウンロードするためのスレッドTHREAD_11を開始し、ROW_Aオブジェクトを使用して、その画像を表示し(私が前に言ったように、ROW_Aオブジェクトが再利用される)

問題はずっと後に、ありますURL_1からIMAGE_1をダウンロードすると、THREAD_1は作業を終了し、IMAGE_1をROW_Aに設定します。 IMAGE_1が表示されます。 その後、THREAD_11も終了し、IMAGE_11をROW_Aに設定します。しかし、ROW_AはIMAGE_1を表示しています。そのため、11行目にIMAGE_1、IMAGE_11が表示されるのはなぜですか。

この問題を解決するには、画像ビューで他のダウンロードスレッドに割り当てられているかどうかを確認する必要があります。つまり、THREAD_1が終了すると、THREAD_1はROW_AがTHREAD_1に属していないことを認識する必要があります。 url:Stringプロパティを使用してUIImageViewサブクラスを作成すると、ダウンロードスレッドの終了時に、ダウンロードしたイメージのURL文字列とurlプロパティの値を比較し、異なる場合はイメージを表示しません。

AFNetworkingを使用して、リモートイメージをダウンロードして表示することもできます。それは非常にシンプルで、Googleで多くのチュートリアルを見つけることができます。

関連する問題