自定义 UITableViewCell - UIImageView 的异步 UIImage

Posted

技术标签:

【中文标题】自定义 UITableViewCell - UIImageView 的异步 UIImage【英文标题】:Custom UITableViewCell - Asynchronous UIImage for UIImageView 【发布时间】:2011-12-01 10:55:48 【问题描述】:

我创建了一个自定义 UITableViewCell,它由 2 个 UILabel 和一个 UIImageView 组成。

与单元格关联的数据可通过名为 CellInfo 的 NSObject 类获得。 CellInfo 有 2 个 NSString 类型的属性和一个 UIImage 属性。

当我在 initWithData 方法(CellInfo 类)中创建 CellInfo 实例时,我执行以下操作:

if(self = [super alloc])

  //initialize strings variables
  self.name = aName;
  self.descritpion = aDescription;
  [self grabImage]    

return self;

其中grabImage(在CellInfo 类中)使用ASIHTTPrequest 框架以异步方式抓取图像(在以下代码中NSURL 始终相同,但实际上它随数据而变化)

- (void)grabImage

   NSURL *url = [NSURL URLWithString:@"http://myurl.com/img.png"];
   __block ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];

   [request setCompletionBlock:^               

      NSData *data = [request responseData];
      UIImage* img = [[UIImage alloc] initWithData:data];

      self.image = img;
      [img release];

      // Send a notification if image has been downloaded
      [[NSNotificationCenter defaultCenter] postNotificationName:@"imageupdated" object:self];
   ];
   [request setFailedBlock:^
      NSError *error = [request error];
     // Set default image to self.image property of CellInfo class
   ];
   [request startAsynchronous];

我还有一个 UITableViewController 可以将数据加载到自定义单元格中,如下所示:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    
    // Do stuff here...

    // Configure the cell...
    ((CustomTableViewCell*)cell).nameOutlet.text = ((CellInfo*) [self.infoArray objectAtIndex:indexPath.row]).name;
    ((CustomTableViewCell*)cell).descriptionOutlet.text = ((CellInfo*) [self.infoArray objectAtIndex:indexPath.row]).descritpion;
    ((CustomTableViewCell*)cell).imageViewOutlet.image = ((CellInfo*) [self.infoArray objectAtIndex:indexPath.row]).image;

    return cell;

上瘾,这个 UITableViewController 观察来自 CellInfo 类的通知,因为在启动时,不显示可见单元格的图像。这是捕获通知时调用的方法:

- (void)imageUpdated:(NSNotification *)notif 

    CellInfo * cInfo = [notif object];
    int row = [self.infoArray indexOfObject:cInfo];
    NSIndexPath * indexPath = [NSIndexPath indexPathForRow:row inSection:0];

    NSLog(@"Image for row %d updated!", row);

    [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]  withRowAnimation:UITableViewRowAnimationNone];

代码运行良好,但我想知道我做得对还是有更好的方法来做到这一点。 我的疑问如下:在每个 CellInfo 实例中保存下载的图像是否正确,或者是否可以采用另一种方式来缓存图像,例如使用 ASIHTTPRequest 提供的缓存策略?

P.S.如果特定 CellInfo 实例的图像已经下载,则不会调用 grabImage。

【问题讨论】:

【参考方案1】:

我相信这很整洁。取而代之的是,您可以继承 UIImageView 类并创建一个类似 [AsyncUIImageView initWithURL:] 的初始化程序,然后将该 ASIHttpRequest 逻辑放入视图中。

加载完图片后,可能有两种方式:

    它可以调用[self setNeedsDisplay]UIView 方法)来重绘图像视图。

    您可以将UITableViewCellUITableView 作为delegate 传递给AsyncUIImgeView,以便它可以告诉表格视图重新加载该单元格。

【讨论】:

以上是关于自定义 UITableViewCell - UIImageView 的异步 UIImage的主要内容,如果未能解决你的问题,请参考以下文章

自定义 UITableViewCell 的首选方式

自定义 UITableViewCell 按钮单击

自定义 UITableViewCell 中的自定义 UIView

自定义UITableViewCell

向自定义 UITableViewCell 输入数据

自定义 UITableViewCell 的 iOS 单元测试