よくある、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にはいつも悩まされます。