简体   繁体   English

从URL加载UITableViewCell的图像(需要异步加载它们)

[英]Loading images for UITableViewCell from URL (need to load them asynchronously)

I have a custom class that parses through an XML and gets URL strings for images (which I store in an array). 我有一个自定义类,它解析XML并获取图像的URL字符串(我存储在一个数组中)。 Then I want to retrieve those strings to load images and display each in a UITableViewCell. 然后我想检索这些字符串以加载图像并在UITableViewCell中显示每个字符串。 Here is my code: 这是我的代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    UILabel *labelText = (UILabel *)[cell viewWithTag:1000];
    labelText.text = [[self.listOfPlaceDetails objectAtIndex:indexPath.row] objectForKey:@"name"];

    NSURL *imageURL = [NSURL URLWithString:[[self.listOfPlaceDetails objectAtIndex:indexPath.row]objectForKey:@"imageCell"]];
    NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
    UIImage *image = [UIImage imageWithData:imageData];
    cell.imageView.image = image;

    return cell;
}

Obviously, when I scroll down the table, the app loads more images, and when the images are loading, the user can't do anything. 显然,当我向下滚动表格时,应用程序会加载更多图像,并且在加载图像时,用户无法执行任何操作。 It looks like the app froze. 看起来应用程序冻结了。 The images I want to load are not very large (about 8kb). 我想加载的图像不是很大(大约8kb)。 Maybe there is a way I could load and store them in the background? 也许有一种方法可以加载并将它们存储在后台? I also want to give more freedom to the user, like scrolling down and viewing cells with text but without an image. 我还希望为用户提供更多自由,例如向下滚动并查看带有文本但没有图像的单元格。 Then force the app to load the images for the cells the user is currently viewing. 然后强制应用加载用户当前正在查看的单元格的图像。

Is there any way to modify my code or any other solution for proper loading of images from URL strings? 有没有办法修改我的代码或任何其他解决方案,以便从URL字符串正确加载图像?

Any advice would be appreciated, thanks. 任何建议将不胜感激,谢谢。

Try to load the images asynchronous, so the main thread doesn't block. 尝试异步加载图像,因此主线程不会阻塞。

Your code would look as follows: 您的代码如下所示:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    UILabel *labelText = (UILabel *)[cell viewWithTag:1000];
    labelText.text = [[self.listOfPlaceDetails objectAtIndex:indexPath.row] objectForKey:@"name"];

    NSURL *imageURL = [NSURL URLWithString:[[self.listOfPlaceDetails objectAtIndex:indexPath.row]objectForKey:@"imageCell"]];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
        UIImage *image = [UIImage imageWithData:imageData];

        dispatch_async(dispatch_get_main_queue(), ^{
            cell.imageView.image = image;
        });    
    });

    return cell;
}

You can use the SDWebImage framework to load images asynchronously. 您可以使用SDWebImage框架异步加载图像。

Please follow the link: https://github.com/rs/SDWebImage 请点击链接: https//github.com/rs/SDWebImage

Just add the SDWebImage framework to your project and set the other linker flag '-ObjC', to use the framework. 只需将SDWebImage框架添加到项目中,并设置其他链接器标志'-ObjC'即可使用该框架。

Download link : https://github.com/rs/SDWebImage/releases 下载链接: https//github.com/rs/SDWebImage/releases

下载此项目并在您的单元格的imageview .. 链接中使用asynimageveiw

Use this for asynchronus way of loading imageview 使用此方法来加载imageview的异步方式

  - (UITableViewCell *)tableView:(UITableView *)_tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

 UILabel *labelText = (UILabel *)[cell viewWithTag:1000];
 labelText.text = [[self.listOfPlaceDetails objectAtIndex:indexPath.row] objectForKey:@"name"];


   //get a dispatch queue
   dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//this will start the image loading in bg
dispatch_async(concurrentQueue, ^{
        NSURL *imageURL = [NSURL URLWithString:[[self.listOfPlaceDetails objectAtIndex:indexPath.row]objectForKey:@"imageCell"]];

    NSData *image = [[NSData alloc] initWithContentsOfURL:imageURL];

    //this will set the image when loading is finished
    dispatch_async(dispatch_get_main_queue(), ^{
       cell.imageView.image = [UIImage imageWithData:image];
    });
      });

   return cell;
   }

Use NSOperation and NSOperationQueue.A perfect solution for your problem.Use below link to see how it works. 使用NSOperation和NSOperationQueue.A解决您的问题的完美解决方案。使用以下链接查看它是如何工作的。

http://www.raywenderlich.com/19788/how-to-use-nsoperations-and-nsoperationqueues http://www.raywenderlich.com/19788/how-to-use-nsoperations-and-nsoperationqueues

Or 要么

Use AFNetworking library It also provide a category over UIImageview that download image asynchronously. 使用AFNetworking库它还提供了一个UIImageview类别,可以异步下载图像。

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

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