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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值