【サンプルコードあり】URLから画像を非同期に取得する

iPhone

画像を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を使う方法です。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

【サンプルコードあり】URLから画像を非同期に取得する2

iPhone

【サンプルコードあり】URLから画像を非同期に取得するの続きです。

前回は、URLから画像をとってきてローディングさせるためのUIImageViewの専用サブクラス、LoadingImageViewを作りました。

次に他クラスで、LoadingImageViewを使って、非同期にURLから画像を取得、表示させる方法です。
また、ローディング中は画像が表示される場所にインジケータアニメーション画像が表示されます。

ストーリーボード編

まず、StoryBoardで、UIImageViewを置き、そのオブジェクトのクラスをLoadingImageViewクラスに変更します。

プログラム編

Sample.h

 #import "LoadingImageView.h"
 @interface Sample : UIViewController
 @property (retain, nonatomic) LoadingImageView *loadingImageView;
 

Sample.m

 _loadingImageView.imageUrl = [NSURL URLWithString: imageURLStr];
 [_loadingImageView startLoadImage];

プロパティのimageUrlに、画像のURLをセットします。
次に、startLoadImageメソッドで、画像を非同期で取得してきます。
その際、画像が取得、表示されるまでシンジケータが表示されます。

今回はmmasashi にお世話になりました。
参考にしてください。
http://d.hatena.ne.jp/mmasashi/20110924/1316940621

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です