简体   繁体   English

使用url设置UIImageView图像

[英]Set UIImageView image using a url

是否可以读取图像的URL并将UIImageView设置为此URL的图像?

NSString *ImageURL = @"YourURLHere";
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:ImageURL]];
imageView.image = [UIImage imageWithData:imageData];

For such a straightforward task I would highly recommend against integrating projects such as Three20, the library is a monster and not very straightforward to get up and running. 对于这样一个简单的任务,我强烈建议不要集成像Three20这样的项目,这个库是一个怪物,不是很容易起床和运行。

I would instead recommend this approach: 我会推荐这种方法:

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 for Swift 3.0 编辑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 for Swift 2.0 *编辑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()

It's possible to load an NSData from a URL and convert that to an image and stick that in the image view, but this is an extremely bad idea because it involves doing a synchronous URL download on the main thread. 可以从URL加载NSData并将其转换为图像并将其粘贴到图像视图中,但这是一个非常糟糕的主意,因为它涉及在主线程上执行同步URL下载。 This will lock up the UI and possibly cause the user to think your app has crashed if the image doesn't download extremely fast. 这将锁定UI并可能导致用户认为如果图像下载速度非常快,您的应用程序已崩溃。

Edit : To clarify, the original question looks to me like the poster wants to say something along the lines of 编辑 :为了澄清,原来的问题在我看来就像海报想要说的一样

imageView.image = [UIImage imageWithContentsOfURL:theURL];

Hence my answer. 因此我的答案。 It's possible to do the equivalent by going through NSData, but it's a bad idea. 通过NSData可以做到相同,但这是一个坏主意。 Instead, the image should be downloaded asynchronously using NSURLConnection, and only once it's fully downloaded should it be converted into a UIImage and assigned to the image view. 相反,应该使用NSURLConnection异步下载图像,并且只有在完全下载后才能将其转换为UIImage并分配给图像视图。

I am using https://github.com/rs/SDWebImage which is a beautifully designed library, which has the options to put a placeholder image, whether to memory, or disk cache the image or use the downloader independent of a UIImageView . 我正在使用https://github.com/rs/SDWebImage这是一个设计精美的库,它可以选择放置占位符图像,无论是内存还是磁盘缓存图像或使用独立于UIImageView的下载程序。

I was trying to do that by myself but the library took all the pain away. 我试图自己做,但图书馆消除了所有的痛苦。

All you need to do is to write the code below for your case : 您需要做的就是为您的案例编写以下代码:

#import "UIImageView+WebCache.h"

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

Worked like a charm for me. 对我来说就像一个魅力。

If you want to display image from Url in ImageView, And also want to save this image in cache for optimize to server interaction this would help you Just pass your imageView object and string Url to this function 如果你想在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]];
    });
});


}

Here's an updated answer to the best answer, as imageWithContentsOfURL is no longer a method of UIImage. 这是最佳答案的更新答案,因为imageWithContentsOfURL不再是UIImage的方法。 You'll have to use CIImage: 你必须使用CIImage:

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

Unfortunately this feature is not available as of this writing... instead you will have to implement the functionality yourself by: 不幸的是,在撰写本文时,此功能无法使用...相反,您必须自己实现以下功能:

  1. Downloading the data of the image 下载图像数据
  2. Saving it or caching it somewhere (db or filesystem) and then 保存它或将其缓存到某个地方(db或文件系统)然后
  3. Setting the UIImaveView to the saved structure 将UIImaveView设置为已保存的结构

Fortunately you don't have to break your head coming out with said functionality as Apple provides an example that does exactly that as part of their code samples. 幸运的是,您不必因为所述功能而出现问题,因为Apple提供了一个示例,可以作为其代码示例的一部分。

Follow the code and I'm sure you will be able to accommodate it to your needs. 遵循代码,我相信您将能够满足您的需求。

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

If you want more, there is a delegate to handle actions after loading 如果你想要更多,有一个委托来加载后处理动作

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

Another option is TTImageView from the Three20 library which handles asynchronous loading of an image. 另一个选项是来自Three20库的TTImageView,它处理图像的异步加载。 The control works great. 控制效果很好。 However, the downside is you have to deal with the nightmare of installing Three20 (which is then almost impossible to fully remove). 然而,缺点是你必须处理安装Three20的噩梦(这几乎是不可能完全删除)。

use AFNetworking category UIImageView+AFNetworking.h 使用AFNetworking类别UIImageView+AFNetworking.h

 #import "UIImageView+AFNetworking.h


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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM