简体   繁体   中英

lazy loading images in tableview

My problem is ---- I am using UITableView in custom cell when load data in tableview it is loading description and title also date but not load images in tableview.some times load all images in one row. When i am using this code scroll is working good but not load images in TableView . I want lazy load concepts. go to below link.

在此处输入图片说明

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
  static NSString *CellIdentifier = @"Cell";
  newsobject=(newscustamCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
  if (newsobject ==nil)
   {
        [[NSBundle mainBundle]loadNibNamed:@"newscustamCell" owner:self options:nil];
   }
    dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
    dispatch_async(q, ^{

         NSURL *url=[NSURL URLWithString:[NSString stringWithFormat:@"%@",[[newsarry objectAtIndex:indexPath.row] objectForKey:@"image_file"]]];

        /* Fetch the image from the server... */

        NSData *data = [NSData dataWithContentsOfURL:url];
        UIImage *img = [[UIImage alloc] initWithData:data];

        dispatch_async(dispatch_get_main_queue(), ^{

            /* This is the main thread again, where we set the tableView's image to
         be what we just fetched. */

         newsobject.allnewsimg.image = img;
    // newsobject.allnewsimg.image=[UIImage imageWithData:data];

        });

    });

      newsobject.allnewsdes.text=[[[newsarry objectAtIndex:indexPath.row]            objectForKey:@"long_desc"]stringByStrippingTags];

       newsobject.allnewslabel.text=[[newsarry objectAtIndex:indexPath.row]        objectForKey:@"title"];
   ![enter image description here][1] 
        newsobject.timelabel.text=[[newsarry objectAtIndex:indexPath.row] objectForKey:@"date"];

     return newsobject;
   }
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
            dispatch_async(queue, ^{

                NSURL *url=[NSURL URLWithString:[NSString stringWithFormat:@"%@",[[newsarry objectAtIndex:indexPath.row] objectForKey:@"image_file"]]];

                NSData *data = [NSData dataWithContentsOfURL:url];
                UIImage *image = [UIImage imageWithData:data];

                dispatch_async(dispatch_get_main_queue(), ^{

            [tableView cellForRowAtIndexPath:indexPath].imageView.image = image;


        });
    });

You can use some Lib like SDWebImage or Afnetworking . Libs support lazy load image and auto cache this image. All you need to do:

[cell.imageView setImageWithURL:[NSURL URLWithString:@"url of image"]
                   placeholderImage:nil];

I will share you some code. Please follow this code.

First you have to retrieve all data from server. After that load on tableview .

Try this code :

- (void)viewDidLoad
{    
   NSString *urlString=@"http://put your url";
   self.responseData=[NSMutableData data];
   NSURLConnection *connection=[[NSURLConnection alloc]initWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlString]] delegate:self];
   NSLog(@"connection====%@",connection);
}

 JSON delegate methods -------------

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
  [self.responseData setLength:0];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
  [self.responseData appendData:data];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
  self.responseData=nil;
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    NSArray *response_Array = [NSJSONSerialization JSONObjectWithData:self.responseRankData options:kNilOptions error:nil];

    NSDictionary *dataDictionary=nil;
    NSDictionary *imgurlDic=nil;
    NSArray *imgDic=nil;

   // I am retrieve image according to my url. So please edit this according to your url. i am just write the format.

    for (int i=0; i < response_Array.count; i++)
    {
        imgurlDic = [imgDic objectAtIndex:i];
        imgDic = [dataDictionary objectForKey:@"imageKey"]; // Take your Key according to URL

        NSURL *url = [NSURL URLWithString:[imgurlDic objectForKey:@"url"]];
        NSData *data = [NSData dataWithContentsOfURL:url];
        UIImage *img = [[UIImage alloc] initWithData:data];
        [self.Img_Array addObject:img]; // Adding all image in your image Array.

        NSLog(@"imgurlDic == %@",imgurlDic);
     }

    [self.tableview reloadData]; // reload your tableview here.
}

Getting all image in your array you can use this array in your cellForRowAtIndexPath method or where you want to load the images.

Because of the way that table view cells are quickly queued/reused, by the time that your network request finishes loading the cell you are referring to might not be the same one you think it is (because it went offscreen and got queued and then reassigned to a different indexPath ). Also, before returning the cell you need to make sure you reset its imageView 's image property to nil or some default value. See my answer here for more info: https://stackoverflow.com/a/23473911/91458

Also - it's a good idea to keep a cache of the images you already retrieved. Check the NSCache class, which is very similar to using a mutable dictionary but with built in memory management, etc.

I also used that trick, but the threads and the indexes between threads make a mess so I searched and I found a great library on GitHub.

You just need to #import <SDWebImage/UIImageView+WebCache.h> to your project, and you can define also the placeholder when image is being downloaded with just this code:

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

        MyObject *object = (MyObject *)[self.list.array objectAtIndex:indexPath.row];

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

        return cell;
}

It also cache downloaded images and gives you great performance.

Hope it will help you!

I hope this link help for you. by using asyn classes image loading async...

https://github.com/nicklockwood/AsyncImageView

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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