使用URL设置UIImageView图像
是否有可能读取图像的url,并设置一个UIImageView的图像在这个url?
可以从URL加载一个NSData并将其转换为图像并将其粘贴到图像视图中,但这是一个非常糟糕的想法,因为它涉及在主线程上执行同步URL下载。 这将locking用户界面,并可能导致用户认为你的应用程序崩溃,如果图像不下载速度非常快。
编辑 :澄清,原来的问题在我看来,像海报想沿线说的东西
imageView.image = [UIImage imageWithContentsOfURL:theURL];
因此我的答案。 通过NSData可以做同样的事情,但这不是一个好主意。 相反,图像应该使用NSURLConnectionasynchronous下载,并且只有在它被完全下载后才能被转换成UIImage并分配给图像视图。
NSString *ImageURL = @"YourURLHere"; NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:ImageURL]]; imageView.image = [UIImage imageWithData:imageData];
对于这样一个直截了当的任务,我强烈build议不要整合像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()
我正在使用https://github.com/rs/SDWebImage这是一个devise精美的图书馆,它可以select放置一个占位符的图像,无论是内存,或磁盘caching的图像或使用独立的;UIImageView
下载器。
我正在试图自己做,但图书馆把所有的痛苦都拿走了。
所有你需要做的是为你的情况写下面的代码:
#import "UIImageView+WebCache.h" [imageView sd_setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"] placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
为我工作就像一个魅力。
如果你想在ImageView中显示来自Url的图像,并且还希望将此图像保存在caching中以优化到服务器交互,这将帮助您将imageView对象和stringUrl传递给此函数
-(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]]; }); }); }
以下是对最佳答案的更新答案,因为imageWithContentsOfURL不再是UIImage的一种方法。 你将不得不使用CIImage:
NSURL *url = [NSURL URLWithString:@"http://url_goes_here.com/logo.png"]; imageView.image = [UIImage imageWithCIImage:[CIImage imageWithContentsOfURL:url]];
不幸的是,这个function在写作时不可用,而是您将不得不通过以下方式来实现这些function:
- 下载图像的数据
- 保存或caching在某处(数据库或文件系统),然后
- 将UIImaveView设置为保存的结构
幸运的是,您不必为了说明function而突破自己的头,因为Apple提供了一个与代码示例完全相同的示例。
按照代码,我相信你将能够适应你的需求。
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
另一个select是来自Three20库的TTImageView,它处理图像的asynchronous加载。 控制效果很好。 然而,缺点是你不得不面对安装Three20的噩梦(这几乎不可能完全消除)。
查看Apple的LazyTableImages的示例代码 – IconDownloader
本示例演示了加载和显示UITableView的多阶段方法。 它从一个RSS源加载相关的文本开始,所以表可以尽可能快地加载,然后以asynchronous的方式下载每一行的图片,这样UI就更加响应了。
由Apple提供的LazyTableImages
使用AFNetworking
类别UIImageView+AFNetworking.h
#import "UIImageView+AFNetworking.h [profileImageView setImageWithURL:[NSURL URLWithString:photoURL] placeholderImage:[UIImage imageNamed:@"placeholder"]];