LoginSignup
67
68

More than 5 years have passed since last update.

UICollectionViewで非同期に画像を取得して表示

Last updated at Posted at 2014-04-19

よくある、Cellに表示する画像を非同期でダウンロードするやつです。
ダウンロード中のくるくるも表示してみます。
セルの再利用を意識してなかったせいで結構ハマったのでメモ。

カスタムセル作成

まずカスタムセルを作ります。

CustomCell.h

#import <UIKit/UIKit.h>

@interface CustomCell : UICollectionViewCell

@property (weak, nonatomic) IBOutlet UIActivityIndicatorView *indicatorView;
@property (weak, nonatomic) IBOutlet UIImageView *imageView;

@end

CustomCell.xibで配置して接続しておきます。

UICollectionView

ViewControler.m

#import "ViewController.h"
#import "CustomCell.h"

static NSString* const kCellIdentifier = @"cell";

@interface ViewController ()<UICollectionViewDataSource, UICollectionViewDelegate>

@property (weak, nonatomic) IBOutlet UICollectionView *collectionView;
@property (nonatomic) NSCache* imageCache;
@property (nonatomic) NSOperationQueue* queue;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self.collectionView registerNib:[UINib nibWithNibName:@"CustomCell" bundle:nil] forCellWithReuseIdentifier:kCellIdentifier];
    self.imageCache = [[NSCache alloc] init];
    self.queue = [[NSOperationQueue alloc] init];
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    CustomCell* cell = [collectionView dequeueReusableCellWithReuseIdentifier:kCellIdentifier forIndexPath:indexPath];

    cell.imageView.image = nil;
    [cell.indicatorView stopAnimating];

    UIImage* image = [self.imageCache objectForKey:indexPath];
    if (image) {
        cell.imageView.image = image;
    } else {
        [cell.indicatorView startAnimating];

        NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"画像のURL"]];

        [NSURLConnection sendAsynchronousRequest:request queue:self.queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
            CustomCell* aCell = (CustomCell *)[collectionView cellForItemAtIndexPath:indexPath];
            UIImage *aImage = [UIImage imageWithData:data];

            [aCell.indicatorView stopAnimating];
            [self.imageCache setObject:aImage forKey:indexPath];
            [collectionView reloadItemsAtIndexPaths:@[indexPath]];
        }];
    }

    return cell;
}

@end

collectionView:cellForItemAtIndexPath:デリゲートメソッドで、まずセルのimageView, indicatorViewを初期状態に戻します。
これを忘れてたので、画像の表示されるセルがおかしくなったりしてハマりました。。。

UITableView, UICollectionViewにはいつも悩まされます。

67
68
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
67
68