Asynchronous image loading in iOS UITableView-Solution
Problem Background:
You need to download an image in each row of UITableView. Previously, placeholder was used. After the image is downloaded, it exists in the cache.
Solution:
Solution 1:
The following code describes how to install and use git on the git page:
#import
...- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString *MyIdentifier = @MyIdentifier; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] autorelease]; } // Here we use the new provided setImageWithURL: method to load the web image [cell.imageView setImageWithURL:[NSURL URLWithString:@http://www.domain.com/path/to/image.jpg] placeholderImage:[UIImage imageNamed:@placeholder.png]]; cell.textLabel.text = @My Text; return cell;}
Solution 2:
Use the asynchronous multithreading of iOS, download the image, save it to the cache, and then use the delegate function to update tableview:
-(Void) reloadRowsAtIndexPaths :( NSArray *) indexPaths withRowAnimation :( UITableViewRowAnimation) animation
Initialization:
@interface ViewController ()@property (strong, nonatomic) NSMutableArray *imageArray;@property (strong, nonatomic) NSCache *imageCache;@property (weak, nonatomic) IBOutlet UITableView *myCustomTableView;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; self.imageCache = [[NSCache alloc] init];}TableView delegate function:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1;}- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { // Number of rows is the number of time zones in the region for the specified section. return 32;}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSLog(@cellForRowAtIndexPath %d, indexPath.row); static NSString *MyIdentifier = @customIdentifier; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier]; if (cell == nil) { cell = [[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier]; } if ([cell isKindOfClass:[CustomTableViewCell class]]) { CustomTableViewCell *customCell = (CustomTableViewCell *)cell; NSData *imageData = [self.imageCache objectForKey:[NSString stringWithFormat:@%d, indexPath.row]]; if(imageData != nil){ customCell.customImageView.image = [UIImage imageWithData:imageData]; } else{ customCell.customImageView.image = [UIImage imageNamed:@test1]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long) NULL), ^(void){ UIImage *image = [self getPictureFromServer]; if (image != nil) { NSData *tmpImageData = UIImagePNGRepresentation(image); [self.imageCache setObject:tmpImageData forKey:[NSString stringWithFormat:@%d, indexPath.row]]; NSLog(@download image for %d, indexPath.row); [self performSelectorOnMainThread:@selector(reloadTableViewDataAtIndexPath:) withObject:indexPath waitUntilDone:NO]; } else{ // do nothing .. } }); } } else{ // do nothing .. } return cell;}ReloadTableViewDataAtIndexPath:
- (void) reloadTableViewDataAtIndexPath: (NSIndexPath *)indexPath{ NSLog(@MyWineViewController: in reload collection view data for index: %d, indexPath.row); NSArray* indexArray = [NSArray arrayWithObjects:indexPath, nil]; [self.myCustomTableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationFade];// [self.myCustomTableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationAutomatic];// [self.myCustomTableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationBottom];// [self.myCustomTableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationLeft];// [self.myCustomTableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationMiddle];// [self.myCustomTableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationNone];// [self.myCustomTableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationRight];// [self.myCustomTableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationTop];}
Download images
- (UIImage *) getPictureFromServer{ UIImage *image = nil; NSString *urlString = [NSString stringWithFormat:@http://yourPicture.jpg]; NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; [request setURL:[NSURL URLWithString:urlString]]; [request setHTTPMethod:@GET]; NSURLResponse *response; NSError *connectionError; NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&connectionError]; if (connectionError == NULL) { NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode]; NSLog(@getPictureFromServer - Response Status code: %ld, (long)statusCode); if (statusCode == 200) { image = [UIImage imageWithData:returnData]; } else{ // do nothing.. } } else{ // do nothing.. } return image;}
Solution 3: (not recommended)
On the basis of solution 2, the change is to load the entire tableview after the image is downloaded, which causes blocking when sliding tableview.
- (void) reloadTableViewData{ NSLog(@MyWineViewController: in reload collection view data); [self.myCustomTableView reloadData];}
Reference link:
Http://stackoverflow.com/questions/15290974/uitableview-on-screen-image-download-lazy-loading
Http://stackoverflow.com/questions/7040740/reload-spefic-uitableview-cell-ios