Est-il possible de lire une URL sur une image et de définir un UIImageView sur l'image située sur cette URL?
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.
NSString *ImageURL = @"YourURLHere";
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:ImageURL]];
imageView.image = [UIImage imageWithData:imageData];
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];
}];
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()
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.
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]];
});
});
}
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]];
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
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:
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.
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).
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.
utilisez AFNetworking
catégorie UIImageView+AFNetworking.h
#import "UIImageView+AFNetworking.h
[profileImageView setImageWithURL:[NSURL URLWithString:photoURL] placeholderImage:[UIImage imageNamed:@"placeholder"]];