web-dev-qa-db-ja.com

URLを使用してUIImageView画像を設定する

画像のURLを読み取り、UIImageViewをこのURLの画像に設定することは可能ですか?

38
jarryd

NSDataをURLから読み込んで画像に変換し、画像ビューに貼り付けることは可能ですが、メインスレッドで同期URLダウンロードを行うため、これは非常に悪い考えです。これにより、UIがロックされ、画像のダウンロードが非常に高速でない場合、ユーザーがアプリがクラッシュしたと思うようになります。

編集:明確にするために、元の質問は、ポスターが線に沿って何かを言いたいように見えます

imageView.image = [UIImage imageWithContentsOfURL:theURL];

したがって、私の答え。 NSDataを使用して同等の処理を実行することは可能ですが、それは悪い考えです。代わりに、NSURLConnectionを使用してイメージを非同期でダウンロードし、完全にダウンロードされた後にのみUIImageに変換してイメージビューに割り当てます。

26
Lily Ballard
NSString *ImageURL = @"YourURLHere";
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:ImageURL]];
imageView.image = [UIImage imageWithData:imageData];
57
Javier Suazo

Three20などのプロジェクトを統合することに対してこのような簡単なタスクを行うことを強くお勧めします。ライブラリはモンスターであり、起動するのはそれほど簡単ではありません。

私は代わりにこのアプローチをお勧めします:

NSString *imageUrl = @"http://www.foo.com/myImage.jpg";
[NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:imageUrl]] queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
    myImageView.image = [UIImage imageWithData:data];
}];

Swift 3.0の編集

let urlString = "http://www.foo.com/myImage.jpg"
guard let url = URL(string: urlString) else { return }
URLSession.shared.dataTask(with: url) { (data, response, error) in
    if error != nil {
        print("Failed fetching image:", error)
        return
    }

    guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {
        print("Not a proper HTTPURLResponse or statusCode")
        return
    }

    DispatchQueue.main.async {
        self.myImageView.image = UIImage(data: data!)
    }
}.resume()

* Swift 2.0の編集

let request = NSURLRequest(URL: NSURL(string: urlString)!)

NSURLSession.sharedSession().dataTaskWithRequest(request) { (data, response, error) -> Void in

    if error != nil {
        print("Failed to load image for url: \(urlString), error: \(error?.description)")
        return
    }

    guard let httpResponse = response as? NSHTTPURLResponse else {
        print("Not an NSHTTPURLResponse from loading url: \(urlString)")
        return
    }

    if httpResponse.statusCode != 200 {
        print("Bad response statusCode: \(httpResponse.statusCode) while loading url: \(urlString)")
        return
    }

    dispatch_async(dispatch_get_main_queue(), { () -> Void in
        self.myImageView.image = UIImage(data: data!)
    })

    }.resume()
54
noobular

私は https://github.com/rs/SDWebImage を使用しています。これは、画像をメモリに保存するか、ディスクにキャッシュするか、またはUIImageViewに依存しないダウンローダー。

私はそれを自分でやろうとしていましたが、図書館はすべての痛みを取り除きました。

あなたがする必要があるのは、あなたのケースのために以下のコードを書くことです:

#import "UIImageView+WebCache.h"

[imageView sd_setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"] placeholderImage:[UIImage imageNamed:@"placeholder.png"]];

私にとって魅力のように働いた。

24
Ugur Kumru

ImageViewのUrlから画像を表示したい場合、また、サーバーとの対話に最適化するためにこの画像をキャッシュに保存したい場合は、imageViewオブジェクトと文字列Urlをこの関数に渡すだけです。

-(void)downloadingServerImageFromUrl:(UIImageView*)imgView AndUrl:(NSString*)strUrl{


strUrl = [strUrl encodeUrl];

NSString* theFileName = [NSString stringWithFormat:@"%@.png",[[strUrl lastPathComponent] stringByDeletingPathExtension]];


NSFileManager *fileManager =[NSFileManager defaultManager];
NSString *fileName = [NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"tmp/%@",theFileName]];



imgView.backgroundColor = [UIColor darkGrayColor];
UIActivityIndicatorView *actView = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
[imgView addSubview:actView];
[actView startAnimating];
CGSize boundsSize = imgView.bounds.size;
CGRect frameToCenter = actView.frame;
// center horizontally
if (frameToCenter.size.width < boundsSize.width)
    frameToCenter.Origin.x = (boundsSize.width - frameToCenter.size.width) / 2;
else
    frameToCenter.Origin.x = 0;

// center vertically
if (frameToCenter.size.height < boundsSize.height)
    frameToCenter.Origin.y = (boundsSize.height - frameToCenter.size.height) / 2;
else
    frameToCenter.Origin.y = 0;

actView.frame = frameToCenter;


dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{

    NSData *dataFromFile = nil;
    NSData *dataFromUrl = nil;

    dataFromFile = [fileManager contentsAtPath:fileName];
    if(dataFromFile==nil){
        dataFromUrl=[[[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:strUrl]] autorelease];                      
    }

    dispatch_sync(dispatch_get_main_queue(), ^{

        if(dataFromFile!=nil){
            imgView.image = [UIImage imageWithData:dataFromFile];
        }else if(dataFromUrl!=nil){
            imgView.image = [UIImage imageWithData:dataFromUrl];  
            NSString *fileName = [NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"tmp/%@",theFileName]];

            BOOL filecreationSuccess = [fileManager createFileAtPath:fileName contents:dataFromUrl attributes:nil];       
            if(filecreationSuccess == NO){
                NSLog(@"Failed to create the html file");
            }

        }else{
            imgView.image = [UIImage imageNamed:@"NO_Image.png"];  
        }
        [actView removeFromSuperview];
        [actView release];
        [imgView setBackgroundColor:[UIColor clearColor]];
    });
});


}
11
SachinVsSachin

ImageWithContentsOfURLはUIImageのメソッドではなくなったため、これがベストアンサーに対する更新されたアンサーです。 CIImageを使用する必要があります。

NSURL *url = [NSURL URLWithString:@"http://url_goes_here.com/logo.png"];
imageView.image = [UIImage imageWithCIImage:[CIImage imageWithContentsOfURL:url]];
4
jenki221

EGOImageLoading

EGOImageView* imageView = [[EGOImageView alloc] initWithPlaceholderImage:[UIImage imageNamed:@"placeholder.png"]];
imageView.frame = CGRectMake(0.0f, 0.0f, 36.0f, 36.0f);

//show the placeholder image instantly
[self.anyView addSubview:imageView];
[imageView release] //if you want

//load the image from url asynchronously with caching automagically
imageView.imageURL = [NSURL URLWithString:photoURL]; 

さらに必要な場合は、ロード後にアクションを処理するデリゲートがあります

@protocol EGOImageViewDelegate<NSObject>
@optional
- (void)imageViewLoadedImage:(EGOImageView*)imageView;
- (void)imageViewFailedToLoadImage:(EGOImageView*)imageView error:(NSError*)error;
@end
2
vk.edward.li

残念ながら、この機能はこの記事の執筆時点では利用できません...代わりに、次の方法で自分で機能を実装する必要があります。

  1. 画像のデータをダウンロードする
  2. 保存またはキャッシュ(dbまたはファイルシステム)してから
  3. UIImaveViewを保存された構造に設定する

幸いなことに、Appleはコードサンプルの一部として 正確にそれを行う例 を提供するので、前述の機能を使用して頭を悩ます必要はありません。

コードに従ってください。あなたはあなたのニーズに対応できると確信しています。

2
samiq

別のオプションは、画像の非同期読み込みを処理するThree20ライブラリのTTImageViewです。コントロールはうまく機能します。ただし、デメリットは、Three20のインストールという悪夢に対処する必要があることです(完全に削除することはほとんど不可能です)。

2
Joel

LazyTableImagesのAppleのサンプルコードを確認してください-IconDownloader

このサンプルは、UITableViewをロードおよび表示するための多段階アプローチを示しています。まず、RSSフィードから関連するテキストを読み込んで、テーブルをできるだけ早く読み込むことができます。次に、各行の画像を非同期にダウンロードして、UIの応答性を高めます。

Apple提供のLazyTableImages

0
tdios

AFNetworkingカテゴリUIImageView+AFNetworking.hを使用します

 #import "UIImageView+AFNetworking.h


[profileImageView setImageWithURL:[NSURL URLWithString:photoURL] placeholderImage:[UIImage imageNamed:@"placeholder"]];
0
Anjali Prasad