2016-09-16 12 views
0

インターネットからダウンロードした一連のアイコンを読み込むサンプルUICollectionViewを使用してアプリケーションを開発しています。したがって、基本的にサーバーはJSONファイル内の各アイコンのURLを含むリストを取得し、解析して各セルが対応するイメージをダウンロードします。UICollectionViewセル画像エラー

このアプローチの問題は、画像のダウンロード中にユーザーがスクロールを開始すると、間違った順序で画像が表示されてしまうことです。それはUICollectionViewが '私を助けよう'としているようなもので、間違った場所にあるコンテンツをレンダリングします!

私はこれについて多くのスレッドを見てきましたが、私は彼らの提案のほとんどを試しましたが、これまでのところ多くの運がありませんでした。誰かがこのような何かを見た?

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { 
PeqImage *image = [self.responseIcons objectAtIndex:indexPath.row]; 

PeqCustomCell *cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:@"PeqCustomCell" forIndexPath:indexPath]; 

cell.peqImage = image; 
cell.imageName = [NSString stringWithFormat:@"%@.png",image.assetId]; 

NSString *theImageUrl = [NSString stringWithFormat:@"http://www.XXXX.com/pb/images/uncompressed/%ld.png",(long)indexPath.row]; 
[cell downloadImage:[NSURL URLWithString:theImageUrl]]; 

return cell; 

}

そして、これは、ダウンロードアルゴリズムは、(UIImageView + AFNetworkingを使用して)どのように見えるかです::

- (void) downloadImageWithUrl:(NSURL*) url completion:(PeqCustomCellCompletionBlock)completionBlock 
{UIImage *placeholder = [UIImage imageNamed:@"placeholder"]; 
NSURLRequest *jpegURLRequest = [NSURLRequest requestWithURL:url]; 

self.imageUrl = url.absoluteString;  
[self.imageView setImageWithURLRequest:jpegURLRequest 
        placeholderImage:placeholder 
        success:^(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *image) { 
        image = [self normalizeImage:image]; 
        completionBlock(image); 
        } 

        failure:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, NSError * _Nonnull error) { 

         NSLog(@"Error downloading image from network"); 
        }]; 
cellForItemAtIndexPathがどのように見えるか

enter image description here

です

}

答えて

1

あなたはスタッフ何かのようなこの種のを処理するためにSDWebImage libraryを使用する必要があり、ここで

#import <SDWebImage/UIImageView+WebCache.h> 

    .. 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
static NSString *MyIdentifier = @"MyIdentifier"; 

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier]; 
if (cell == nil) { 
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
            reuseIdentifier:MyIdentifier] autorelease]; 
} 

// Here we use the new provided sd_setImageWithURL: method to load the web image 
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"] 
        placeholderImage:[UIImage imageNamed:@"placeholder.png"]]; 

cell.textLabel.text = @"My Text"; 
return cell; 
} 

はあなたのcollection viewに同じ使用できるテーブルビューの一例です!

このライブラリはイメージを再利用するためにキャッシュします。

あなたはこのようなもののnative wayを実装するか知りたいなら、あなたはLoading Images in UICollectionViewCell: Naive to the Clever.

+0

この回答ありがとうございます。私はトリックをやった!私は別のライブラリ (UIImageView + AFNetworking)を使用していましたが、SDWebImageの方が遅いようですが、画像をダウンロードする方法で動作します! –

0

問題は、セルが非表示になって再び表示されるたびにイメージを再ダウンロードすることです。より良い方法は、すべてのデータを事前にダウンロードし、それを使用してcollectionViewを作成することです。

+0

いいえ、事前にすべての画像を読み込まないでください。必要に応じてそれらを一度ずつロードしてキャッシュします。コレクションビューに何百ものアイテムがありますが、ユーザーがスクロールしてほとんどのアイテムを表示しない場合はどうなりますか?なぜそれらのすべてをダウンロードするのですか? – rmaddy

1

私はスレッドを原因と考えています。すべてのUIコードはメインスレッドから呼び出す必要があります。最近では、非常に多くのブロックが使用されているため、誤ってバックグラウンドスレッドからUIコールを作成するのは簡単です。これをすると、すべての奇妙さが現実化し始めます。

私はコードの最後のスニペットをこれに変更して、イメージの呼び出しがメインスレッドでディスパッチされるようにしようとしています。私はdispatch_async()関数を追加しました。

self.imageUrl = url.absoluteString; 
[self.imageView setImageWithURLRequest:jpegURLRequest 
         placeholderImage:placeholder 
           success:^(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *image){ 
            dispatch_async(dispatch_get_main_queue(), ^{ 
            image = [self normalizeImage:image]; 
            completionBlock(image); 
            }); 
           } 
           failure:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, NSError * _Nonnull error) { 
            NSLog(@"Error downloading image from network"); 
           }]; 
1

を参照することができ、問題はコレクションビュー細胞が再利用されていることです。つまり、画面上で特定の画像をダウンロードするようにセルに指示してから、オフスクリーンになり、コレクションビューに別のセルが必要なときに再利用され、別の画像をダウンロードするようにSAMEセルに指示しています。どちらの画像でも最後にダウンロードが終了した画像が最後に表示されます。

ダウンロード完了ブロックでimage = [self normalizeImage:image];を設定する前に、リクエストURLが現在のself.imageUrlと一致するかどうかを確認する必要があります。そうでない場合、イメージは古いリクエストに由来し、セルに表示する必要はありません。

関連する問題