2016-05-14 7 views
0

私は画像付きのコレクションビューを持っています。ネットワークコードにAlamofireとAlamofireImageを使用しています。 cellForItemAtIndexPathの先頭で、画像をnilに設定し、飛行中のリクエストが存在する場合は、リクエスト?.cancel()を使用してキャンセルします。 これを行うと、一部のセルには画像がまったく入力されません。 私が間違っていることを私に見せてもらえますか? 以下の私のcellForItemAtIndexPathコードを参照してください:request.cancel()再利用セル用Alamofire swift

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { 
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! StoreCell 

    let entry = self.dataCell.addCell[indexPath.section][indexPath.item] 

    stringURL = "https://website.com/stories_db/images/\(entry.filename)" 

    cell.title.text = entry.title 
    cell.subTitle.text = entry.author 
    cell.cost.text = entry.cost 

    // Reset the cell 
    cell.storyImage.image = nil 
// request?.cancel() 

    if let image = dataCell.cachedImage(stringURL) { 
     cell.storyImage.image = image 
    } else { 
     request = dataCell.getNetworkImage(stringURL) { image in 
      cell.storyImage.image = image 
     } 
    } 

    // Fix the collection view cell in size 
    cell.contentView.frame = cell.bounds 
    cell.contentView.autoresizingMask = [UIViewAutoresizing.FlexibleWidth, UIViewAutoresizing.FlexibleHeight] 

    return cell 
} 

答えて

1

あなたがイメージ要求を格納するための要求と呼ばれる単一VARを再利用しているように見えます。一度に複数のコレクションビューセルが表示される場合は、一度に1つ以上の非同期イメージ要求を行う必要があるため、複数の進行中の要求を格納する方法が必要になる場合があります。

たとえば、コレクションビューに3つのセルがあり、すべてが表示されている場合は、リロード時にcellForItemAtIndexPathを呼び出して最初のセルを取得します。あなたのコードはセルを作成し、 "イメージ1"の非同期リクエストを開始し、それをリクエストvarに格納します。

次に、コレクションビューは直ちにcellForItemAtIndexPathを呼び出して2番目のセルを取得します。 "Image 1"のリクエストがまだ進行中の場合、 "?1"というリクエストが.concel()を呼び出すと、 "Image 1"のダウンロードが完了しません。次に、コードは "Image 2"の新しい要求を作成し、それを要求に割り当てます。

コレクションビューはすぐに第三のセルを取得するためにcellForItemAtIndexPathを呼び出して...

一つの解決策は、アクティブな要求の配列(または辞書)を格納することです。リクエストを作成するときにリクエストを追加し、リクエストが完了したときに削除します(失敗または成功)。次に、再利用しようとしているセルに対して進行中のリクエストがあると判断した場合は、そのリクエストをキャンセルしてリストから削除します。

カスタムセルサブクラスを作成してアクティブリクエストを格納する方法もあります。これには、要求をセルに関連付けるのが簡単になるという利点があります。

いずれの方法を使用する場合でも、cellForItemAtIndexPathの代わりにUICollectionViewCell.prepareForReuse()でセルのアクティブな要求をキャンセルすることを検討してください。

関連する問題