iOS UITableView中异步加载图片 - 解决方案
问题背景:
需要在UITableView中的每一行下载图片,之前使用placeholder,下载好后存在cache中。
解决方案:
方案一:
使用SDWebImage:https://github.com/rs/SDWebImage
如何安装及使用在git页面有详细解释,具体使用的代码:
#import <SDWebImage/UIImageView+WebCache.h> ... - (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<span style="font-family: Arial, Helvetica, sans-serif;">.</span><span style="font-family: Arial, Helvetica, sans-serif;">jpg"];</span> 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
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。