14

Intagram のようなアプリUICollectionViewsが写真のフィードを表示するために使用していることに気付きました。また、実際の写真が完全にダウンロードされる前に、これらの写真のセルが何らかの形で画面に配置されていることにも気付きました。ダウンロードが完了すると、その写真が適切なセルに表示されます。

その機能をコピーしたいのですが、その方法がわかりません。

現在、 NSDictionariesの配列に変換する大きなJSONオブジェクトをダウンロードしています。それぞれに各写真に関する情報が含まれており、その情報の中に URL が表示されます。この URL で、ダウンロードして表示する必要がある対応する画像を見つけることができます。NSDictionaryUICollectionViewCells

今のところ、このリストを繰り返し、表示される URL ごとにダウンロードを開始します。ダウンロードが完了したら、を使用して collectionview をリロードし[self.collectionView reloadData]ます。しかし、ご想像のとおり、30 個のセルがすべて画像を必要としている場合、多くのreloadData呼び出しが発生します。

私は AFNetworking を使用してダウンロードを処理しています。これが、前述の URL に基づいて呼び出すメソッドです。

-(void) downloadFeedImages:(NSString *) photoURL imageDescs:(NSDictionary*)imageDescs photoId:(NSString *)photoID{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    NSString *directory = [paths objectAtIndex:0];

    NSString* foofile = [directory stringByAppendingPathComponent:photoID];

    if([[NSFileManager defaultManager] fileExistsAtPath:foofile]){
        // IF IMAGE IS CACHED
        [self.collectionView reloadData];
        return;
    }

    NSLog(@"photoURL: %@", photoURL);
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:photoURL]];
    AFImageRequestOperation *operation = [AFImageRequestOperation imageRequestOperationWithRequest:request
                                                                              imageProcessingBlock:nil
                                                                                           success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
                                                                                               // Save Image
                                                                                               NSLog(@"URL-RESPONSE:%@", image);
                                                                                               NSString *myFile = [directory stringByAppendingPathComponent:photoID];

                                                                                               NSData *imageData = UIImagePNGRepresentation(image);
                                                                                               [imageData writeToFile:myFile  atomically: YES];
                                                                                               [self.collectionView reloadData];
                                                                                           }
                                                                                           failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
                                                                                               NSLog(@"ERROR: %@", [error localizedDescription]);
                                                                                           }];
    [[WebAPI sharedInstance] enqueueHTTPRequestOperation:operation];
}

基本的に、画像付きのフィードを表示する際に、Instagram や同様のアプリケーションが持つ機能をどのように実現できるのだろうかと思いますさらに、各セルのダウンロードを開始する良い方法を知りたいです。そのダウンロードが終了したら、[reloadData]を使用してビュー全体を再描画するのではなく、そのセルを更新します。

ありがとう

4

3 に答える 3

16

実装したい手法は、遅延読み込みと呼ばれます。あなたが使用しているのでAFNetworking、あなたのケースでこれを実装するのは簡単です。UIImageView画像を表示するには、各コレクション ビュー セルに が必要です。カテゴリを使用し、UIImageView+AFNetworking.hメソッドを呼び出して正しい画像 URL を設定します

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    // ....

    [cell.imageView setImageWithURL:imageURL placeholderImage:[UIImage imageNamed:@"placeholder.png"]];

    // ...
    return cell;
}

プレースホルダーは、必要な画像がダウンロードされるまで表示される画像です。これにより、必要なジョブが実行されます。

: デフォルトでは、URL リクエストには のキャッシュ ポリシーNSURLCacheStorageAllowedと 30 秒のタイムアウト間隔があり、Cookie を処理しないように設定されています。URL 要求を別の方法で構成するには、 を使用しますsetImageWithURLRequest:placeholderImage:success:failure:

また、参考までに、画像の遅延読み込みを自分で実装する場合は、このApple サンプル コードに従ってください。これは for ですUITableViewが、同じテクニックを forUICollectionViewにも使用できます。

それが役立つことを願っています!

于 2013-08-27T07:38:53.370 に答える