2

Sorry for question title. I can not find a suitable title.

I have UITableView content images from url when i open the UITableView the View did not show until the images loaded and that takes along time.

I get the images from JSON by php.

I want to show the table and then images loading process.

This is code from my app:

NSDictionary *info = [json objectAtIndex:indexPath.row];
cell.lbl.text = [info objectForKey:@"title"];
NSString *imageUrl = [info objectForKey:@"image"];
cell.img.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageUrl]]];
[cell.img.layer setBorderColor: [[UIColor blackColor] CGColor]];
[cell.img.layer setBorderWidth: 1.0];

return cell;

Sorry my english is weak.

evlogii
  • 811
  • 1
  • 7
  • 17
Khalid
  • 33
  • 1
  • 4

4 Answers4

7

Perform the web request on a separate thread, to not block the UI. Here is an example using NSOperation. Remember to only update the UI on the main thread, as shown with performSelectorOnMainThread:.

- (void)loadImage:(NSURL *)imageURL
{
    NSOperationQueue *queue = [NSOperationQueue new];
    NSInvocationOperation *operation = [[NSInvocationOperation alloc]
                                        initWithTarget:self
                                        selector:@selector(requestRemoteImage:)
                                        object:imageURL];
    [queue addOperation:operation];
}

- (void)requestRemoteImage:(NSURL *)imageURL
{
    NSData *imageData = [[NSData alloc] initWithContentsOfURL:imageURL];
    UIImage *image = [[UIImage alloc] initWithData:imageData];

    [self performSelectorOnMainThread:@selector(placeImageInUI:) withObject:image waitUntilDone:YES];
}

- (void)placeImageInUI:(UIImage *)image
{
    [_image setImage:image];
}
Joe Masilotti
  • 16,815
  • 6
  • 77
  • 87
  • i have more than one image how can i refresh each cell after loaded cell's image – Khalid Aug 27 '12 at 13:00
  • 1
    Take a look at http://developer.apple.com/library/ios/#samplecode/LazyTableImages/Introduction/Intro.html. It looks to be what you need. – Joe Masilotti Aug 28 '12 at 01:55
  • NSInvocationOperation only accepts one argument in the object. i want to send the image's URL and the indexPath.row (2 arguments ) how can i do that ? – Khalid Aug 28 '12 at 17:05
  • Wrap the two in an `NSArray` or `NSDictionary`. – Joe Masilotti Aug 28 '12 at 17:38
  • Or [set `NSInvocation` arguments explicitly](http://stackoverflow.com/questions/4555252/selector-with-multiple-arguments) – Joe Masilotti Aug 28 '12 at 17:45
  • the approach above works much, much faster than loading the url in a background thread. (thank you Joe Masilotti!) – tmr Mar 26 '15 at 00:33
2

You have to use NSURLConnection and NSURLRequest. First create and show your empty table view (maybe with placeholder images, that are stored locally in the app). Then you start sending requests. These requests will run in the background and you (the delegate) will be notified when a request is completed. After that you can show the image to the user. Try not to load all the images at once if you have a lot of them. And don't load the ones that are invisible to the user, only load those if he scrolls down.

DrummerB
  • 39,814
  • 12
  • 105
  • 142
1

There is a UITableView lazy image loading example that Apple provided: https://developer.apple.com/library/ios/#samplecode/LazyTableImages/Introduction/Intro.html

Hopefully it's what you were looking for

Novarg
  • 7,390
  • 3
  • 38
  • 74
0

This is among very common thing we do in our application.

You simply can have store the URLs in a persistent store e.g array or db & can get the images using Operation queue to download faster. You can set the priorities, cancel operations at anytime etc. Also, the application respond time will be quicker.

Tarun
  • 766
  • 1
  • 5
  • 12