Reputation: 6940
I have a custom class that parses through an XML and gets URL strings for images (which I store in an array). Then I want to retrieve those strings to load images and display each in a 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). 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?
Any advice would be appreciated, thanks.
Upvotes: 2
Views: 2094
Reputation: 1258
You can use the SDWebImage framework to load images asynchronously.
Please follow the link: https://github.com/rs/SDWebImage
Just add the SDWebImage framework to your project and set the other linker flag '-ObjC', to use the framework.
Download link : https://github.com/rs/SDWebImage/releases
Upvotes: 3
Reputation: 434
Use this for asynchronus way of loading 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;
}
Upvotes: 2
Reputation: 1465
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;
}
Upvotes: 3
Reputation: 178
Use NSOperation and NSOperationQueue.A perfect solution for your problem.Use below link to see how it works.
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.
Upvotes: 1