ios UITableView 中的延迟加载图片

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1130089/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 16:10:27  来源:igfitidea点击:

Lazy load images in UITableView

iphoneiosobjective-cuitableview

提问by

I have some 50 custom cells in my UITableView. I want to display an image and a label in the cells where I get the images from URLs.

我的UITableView. 我想在从 URL 获取图像的单元格中显示图像和标签。

I want to do a lazy load of images so the UI does not freeze up while the images are being loaded. I tried getting the images in separate threads but I have to load each image every time a cell becomes visible again (Otherwise reuse of cells shows old images). Can someone please tell me how to duplicate this behavior.

我想延迟加载图像,以便在加载图像时 UI 不会冻结。我尝试在单独的线程中获取图像,但每次单元格再次可见时我都必须加载每个图像(否则单元格的重用会显示旧图像)。有人可以告诉我如何复制这种行为。

回答by TamilKing

Try AFNetworkingclass download this class in this link https://github.com/AFNetworking/AFNetworking. Add the all AFNetworking class in your project.Then just import this category

尝试在此链接https://github.com/AFNetworking/AFNetworking 中下载此类AFNetworking类。在您的项目中添加所有 AFNetworking 类。然后只需导入此类别

#import "UIImageView+AFNetworking.h" in your Viewcontroller which contains your Tableview.

Then in cellForRowAtIndexPath:put like below

然后在cellForRowAtIndexPath: 中放置如下

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];

    if (cell == nil) 
    {
        cell = [[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
    }

    [cell.imageView setImageWithURL:[NSURL URLWithString:[UrlArray objectAtIndex:indexPath.row]] placeholderImage:[UIImage imageNamed:@"placeholder.jpg"]];
     cell.myLabel.text = [imageNameArray objectAtIndex:indexPath.row];

     cell.selectionStyle = UITableViewCellSelectionStyleNone;

    return cell;    
}

This download your Image for imageView in the UITableviewcellasynchronously. It wont download again and again while the user scroll the Tableview, because it has cache also. Once your image download it save the image with key of your imageUrl. I hope it useful for you.

这将异步下载UITableviewcell 中 imageView 的图像。当用户滚动 Tableview 时,它不会一次又一次地下载,因为它也有缓存。下载图像后,它会使用 imageUrl 的键保存图像。我希望它对你有用。

回答by natanavra

I'd suggest going for an NSOperation and doing whatever you need on another thread.

我建议去 NSOperation 并在另一个线程上做任何你需要的事情。

This is a class I wrote for image loading:

这是我为图像加载编写的类:

- (id)initWithTarget:(id)trgt selector:(SEL)sel withImgURL:(NSString *)url {
    if(self = [super init]) {
        if(url == nil || [url isEqualToString:@""])
            return nil;
        target = trgt;
        action = sel;
        imgURL = [[NSURL alloc] initWithString: url];
    }
    return self;
}

- (void)main {
    [NSThread detachNewThreadSelector:@selector(loadImage) toTarget:self withObject:nil];
}

- (void)loadImage {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    UIImage *img = [UIImage imageNamed: @"default_user.png"];
    if(![[imgURL absoluteString] isEqualToString: @"0"]) {
        NSData *imgData = [NSData dataWithContentsOfURL: imgURL];
        img = [UIImage imageWithData: imgData];
    }
    if([target respondsToSelector: action])
        [target performSelectorOnMainThread: action withObject: img waitUntilDone: YES];
    [pool release];
}

- (void)dealloc {
    [imgURL release];
    [super dealloc];
}

Hope that helps!

希望有帮助!

回答by Divine_Code

you can use ego image button..you can download ego image button files from github...add in your project....

您可以使用 ego 图像按钮...您可以从 github 下载 ego 图像按钮文件...添加到您的项目中....

change the class " ego image button" at image view in your xib...

在您的 xib 的图像视图中更改“自我图像按钮”类...

lazy loading is called synchronous request..

延迟加载称为同步请求..

ego image is called asynchronous request. ego image dont wait for response..display all images at one time..

自我形象被称为异步请求。自我图像不要等待响应..一次显示所有图像..

回答by ShujatAli

you can try this lazyTableImages,

你可以试试这个lazyTableImages



i had customized lazyTableImages this project into a very simple one (customizeLazyTableImages) and removed all extra codes with some static urls and titles only this is loading images very smoothly and caching them

我已经将这个项目自定义为一个非常简单的项目(customizeLazyTableImages),并删除了所有带有一些静态 url 和标题的额外代码,只有这样才能非常顺利地加载图像并缓存它们



回答by jiachunke

Maybe you can have a try ALImageView.It is much simpler than SDWebImage.You only need two source files(ALImageView.h/ALImageView.m).You can reuse the image view to reload different urls in a tableview cell.

也许你可以试试ALImageView 。它比 SDWebImage 简单得多。你只需要两个源文件(ALImageView.h/ALImageView.m)。你可以重用图像视图来重新加载 tableview 单元格中的不同 url。

  1. Support local and memory cache;
  2. Support place holders;
  3. Support tap touch(target-action);
  4. Support corner for the image view;
  1. 支持本地和内存缓存;
  2. 支持占位符;
  3. 支持点击触摸(target-action);
  4. 支持转角图像查看;

There is also a good demo.

还有一个很好的演示。

回答by vikram

You can use the NSOperation queue or GCD for loading images in the background.

您可以使用 NSOperation 队列或 GCD 在后台加载图像。

If you don't want to load images again and again, you can use NSCache or the file system for storing the images.

如果你不想一次又一次地加载图像,你可以使用 NSCache 或文件系统来存储图像。

回答by Emon

I think there is another way to solve that problem if you want to load that image then at the start of the view thats mean

我认为如果您想加载该图像,则有另一种方法可以解决该问题,然后在视图开始时

when -(void)loadViewis loading, then just allocate these images and take it into a nsarraynow when table cell is loading then make your view at the table cell and according to the indexPath.rowjust replace these images of nsarrayinto that view as a background image or make subview of these images on that new view of tablecell using nsarrayindex and indexPath.rowof the tableview cell.

-(void)loadView是加载,然后就分配这些图像,并把它变成一个nsarray现在当表格单元加载,然后让你的观点在表格单元格,并根据indexPath.row只需更换这些图像nsarray该检视这些画面的背景图像或进行子视图在使用nsarray索引和indexPath.rowtableview 单元格的 tablecell 的新视图上。

回答by Jon Steinmetz

I am not aware of any built in way to accomplish this but it sounds like you have something working with another thread already.

我不知道有什么内置的方法来完成这个,但听起来你已经有一些东西可以与另一个线程一起工作了。

Assuming that your only remaining problem now is invalidating the contents of a cell when it comes back into view you should look at:

假设您现在唯一剩下的问题是当单元格重新出现时使单元格的内容无效,您应该查看:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath

By implementing this delegate method you could check the contents of the cell before it draws to see if it needs new contents. If it does then you could empty the cells contents and trigger your threaded loading again.

通过实现这个委托方法,你可以在绘制之前检查单元格的内容,看看它是否需要新内容。如果是,那么您可以清空单元格内容并再次触发您的线程加载。

You might also consider posting some code.

您也可以考虑发布一些代码。