画像をURLから取得するとき、非同期で行うようにしたいとおもいます。
まず、専用のImageViewのサブクラスをつくります。
LoadingImageView.h
@interface LoadingImageView : UIImageView - (id)initWithFrame:(CGRect)frame withUrl:(NSURL *)url; // Start load the image of the specified url. // Doesn't load the image if an image has been already set. - (void)startLoadImage; // Reload load the image of the specified url. // Load the image even if a connection was already created. - (void)reloadImage; // Cancel loading if requesting. - (void)cancelLoading; // Set the url of the image to reqeust. @property (nonatomic, retain) NSURL *imageUrl; @end
LoadingImageView.m
#import "LoadingImageView.h" typedef enum LazyImageViewTag_ { LazyImageViewTagIndicatorView = 1, } LazyImageViewTag; @interface LoadingImageView () - (void)setLoadingImage; - (void)setLoadErrorImage; @property (nonatomic, retain) NSURLConnection *connection; @property (nonatomic, retain) NSMutableData *imgData; @end @implementation LoadingImageView - (id)initWithFrame:(CGRect)frame withUrl:(NSURL *)url { self = [super initWithFrame:frame]; if (self) { [self setImageUrl:url]; } return self; } - (void)startLoadImage { if (self.image) return; if (self.connection) { [self.connection cancel]; } [self setImgData:[NSMutableData data]]; NSURLRequest *req = [NSURLRequest requestWithURL:self.imageUrl]; NSURLConnection *con = [NSURLConnection connectionWithRequest:req delegate:self]; [self setConnection:con]; [self setLoadingImage]; } - (void)reloadImage { [self setImage:nil]; [self startLoadImage]; } - (void)cancelLoading { [self.connection cancel]; [self setConnection:nil]; if (self.image == nil) { [self setLoadErrorImage]; } } #pragma mark - NSURLConnectionDelegate - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { [self.imgData appendData:data]; } - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { [self setLoadErrorImage]; } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { UIActivityIndicatorView *iv = (UIActivityIndicatorView *) [self viewWithTag:LazyImageViewTagIndicatorView]; if (iv) [iv removeFromSuperview]; [self setImage:[UIImage imageWithData:self.imgData]]; } #pragma mark - - (void)setLoadingImage { UIActivityIndicatorView *iv = (UIActivityIndicatorView *) [self viewWithTag:LazyImageViewTagIndicatorView]; if (iv == nil) { iv = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; // [iv setCenter:CGPointMake(self.frame.size.width/2, self.frame.size.height/2)]; [iv setTag:LazyImageViewTagIndicatorView]; [self addSubview:iv]; } iv.frame = self.frame; iv.center = self.center; [iv startAnimating]; [iv setHidden:NO]; //[self setBackgroundColor:[UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.3]]; [self setBackgroundColor:[UIColor clearColor]]; } - (void)setLoadErrorImage { UIActivityIndicatorView *iv = (UIActivityIndicatorView *) [self viewWithTag:LazyImageViewTagIndicatorView]; [iv removeFromSuperview]; [self setImage:nil]; //[self setBackgroundColor:[UIColor colorWithRed:0.3 green:0.3 blue:0.3 alpha:0.4]]; [self setBackgroundColor:[UIColor blackColor]]; } #pragma mark - - (void)dealloc { [self setImageUrl:nil]; [self.connection cancel]; [self setConnection:nil]; [self setImgData:nil]; } @synthesize imageUrl; @synthesize connection; @synthesize imgData; @end
今回はmmasashi にお世話になりました。
参考にしてください。
http://d.hatena.ne.jp/mmasashi/20110924/1316940621
続きは、【サンプルコードあり】URLから画像を非同期に取得する2です。
他クラスからLoadingImageViewを使う方法です。