Пользовательский UITableViewCell - асинхронный UIImage для UIImageView - PullRequest
1 голос
/ 01 декабря 2011

Я создал пользовательский UITableViewCell, который состоит из 2 UILabels и одного UIImageView.

Данные, связанные с ячейками, доступны с помощью класса NSObject CellInfo.CellInfo имеет 2 свойства типа NSString и свойство UIImage.

Когда я создаю экземпляр CellInfo, внутри метода initWithData (класс 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?

PS grabImage не вызывается, если изображение для определенного экземпляра CellInfo уже загружено.

1 Ответ

0 голосов
/ 09 августа 2012

Я считаю, что это довольно опрятно. Вместо этого вы можете создать подкласс UIImageView class и создать инициализатор типа [AsyncUIImageView initWithURL:], а затем поместить эту логику ASIHttpRequest в представление.

После завершения загрузки картинки возможны два пути:

  1. Может вызываться [self setNeedsDisplay] (метод UIView), поэтому представление изображения перерисовывается.

  2. Вы можете передать UITableViewCell или UITableView как delegate в AsyncUIImgeView, чтобы он мог указать табличному представлению перезагрузить эту ячейку.

...