web-dev-qa-db-fra.com

Définir l'image UIImageView à l'aide d'une URL

Est-il possible de lire une URL sur une image et de définir un UIImageView sur l'image située sur cette URL?

37
jarryd

Il est possible de charger un NSData à partir d'une URL et de le convertir en une image et de le coller dans la vue d'image, mais c'est une très mauvaise idée car cela implique de télécharger simultanément une URL sur le fil principal. Cela verrouille l'interface utilisateur et peut éventuellement amener l'utilisateur à penser que votre application s'est écrasée si l'image ne se télécharge pas très rapidement.

Modifier : Pour clarifier, la question initiale me donne l’impression que l’affiche veut dire quelque chose dans le sens de

imageView.image = [UIImage imageWithContentsOfURL:theURL];

D'où ma réponse. Il est possible de faire l'équivalent en passant par NSData, mais c'est une mauvaise idée. Au lieu de cela, l'image doit être téléchargée de manière asynchrone à l'aide de NSURLConnection. Une fois qu'elle est entièrement téléchargée, elle doit être convertie en un UIImage et attribuée à la vue d'image.

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

Pour une tâche aussi simple, je recommanderais vivement de ne pas intégrer de projets tels que Three20, la bibliothèque est un monstre et n'est pas très simple à mettre en place.

Je recommanderais plutôt cette approche:

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];
}];

EDIT pour 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()

* EDIT pour 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

J'utilise https://github.com/rs/SDWebImage qui est une bibliothèque magnifiquement conçue, qui offre la possibilité de placer une image fictive, en mémoire ou en mémoire cache, ou d'utiliser le téléchargeur indépendamment de un UIImageView.

J'essayais de le faire moi-même mais la bibliothèque a enlevé toute la douleur.

Tout ce que vous avez à faire est d'écrire le code ci-dessous pour votre cas:

#import "UIImageView+WebCache.h"

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

A fonctionné à merveille pour moi.

24
Ugur Kumru

Si vous souhaitez afficher une image à partir de l'URL dans ImageView et que vous souhaitez également enregistrer cette image dans le cache pour optimiser l'interaction serveur, cela vous aiderait. Il vous suffit de passer votre objet imageView et la chaîne URL à cette fonction

-(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

Voici une réponse actualisée à la meilleure réponse, car imageWithContentsOfURL n'est plus une méthode de UIImage. Vous devrez utiliser CIImage:

NSURL *url = [NSURL URLWithString:@"http://url_goes_here.com/logo.png"];
imageView.image = [UIImage imageWithCIImage:[CIImage imageWithContentsOfURL:url]];
3
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]; 

Si vous voulez plus, il y a un délégué pour gérer les actions après le chargement

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

Malheureusement, cette fonctionnalité n'est pas disponible au moment de la rédaction de cet article ... mais vous devrez l'implémenter vous-même en: 

  1. Téléchargement des données de l'image 
  2. Sauvegarde ou mise en cache quelque part (db ou système de fichiers) puis 
  3. Paramétrer UIImaveView sur la structure enregistrée 

Heureusement, vous n'avez pas à vous casser la tête avec cette fonctionnalité, car Apple fournit un exemple qui fait exactement cela } dans le cadre de leurs exemples de code.

Suivez le code et je suis sûr que vous pourrez l'adapter à vos besoins.

2
samiq

Une autre option est TTImageView de la bibliothèque Three20 qui gère le chargement asynchrone d’une image. Le contrôle fonctionne très bien. Cependant, l'inconvénient est que vous devez faire face au cauchemar de l'installation de Three20 (qu'il est alors presque impossible de supprimer complètement).

2
Joel

Découvrez l'exemple de code Apple pour LazyTableImages - IconDownloader

Cet exemple illustre une approche en plusieurs étapes du chargement et du afficher une UITableView. Il commence par charger le texte correspondant à partir de un flux RSS pour que la table puisse se charger le plus rapidement possible, puis télécharge les images pour chaque ligne de manière asynchrone, de sorte que l'interface utilisateur est plus. sensible.

LazyTableImages fournies par Apple

0
tdios

utilisez AFNetworking catégorie UIImageView+AFNetworking.h

 #import "UIImageView+AFNetworking.h


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