iOS UITableView中非同步載入圖片 - 解決方案
問題背景:
需要在UITableView中的每一行下載圖片,之前使用placeholder,下載好後存在cache中。
解決方案:
方案一:
如何安裝及使用在git頁面有詳細解釋,具體使用的代碼:
#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;}
方案二:
使用iOS自有的非同步多線程,下載好圖片後存入cache,再使用delegate函數更新tableview:
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
初始化:
@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函數:
- (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];}
下載圖片
- (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;}
方案三:(不推薦)
在方案二的基礎上,變動在於下載好圖片後load整個tableview,缺點時會引起滑動tableview時阻塞。
- (void) reloadTableViewData{ NSLog(@MyWineViewController: in reload collection view data); [self.myCustomTableView reloadData];}
參考連結:
http://stackoverflow.com/questions/15290974/uitableview-on-screen-image-download-lazy-loading
http://stackoverflow.com/questions/7040740/reload-spefic-uitableview-cell-ios