ios - library - swift libraries
El tamaño de UITableViewCell cambia de tamaño cuando se descarga la imagen (2)
Debe almacenar la imagen descargada en la memoria o en el disco, por lo que la próxima vez que intente obtener imágenes de esta URL, recibirá de la memoria caché.
Entonces, si haces eso, tendrás que hacer algo como esto:
[tableView beginUpdates];
[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
Y debe devolver la altura de la nueva celda en este método de fuente de datos de vista de tabla:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
Le recomendaría utilizar la biblioteca SDWebImage en lugar de AFNetworking
porque puede almacenar en caché sus imágenes en Memcache y en el disco, y es muy fácil de usar. Entonces, si decide usarlo, su código de descarga de imágenes se verá así:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
...
[cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:@"placeholder.png"]
success:^(UIImage *image, BOOL cached) {
// save height of an image to some cache
[self.heightsCache setObject:[NSNumber numberWithFloat:imHeight]
forKey:urlKey];
[tableView beginUpdates];
[tableView reloadRowsAtIndexPaths:@[indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
}
failure:^(NSError *error) {... failure code here ...}];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
// try to get image height from your own heights cache
// if its is not there return default one
CGFloat height = [[self.heightsCache objectForKey:urlKeyFromModelsArrayForThisCell] floatValue];
...
return newHeight;
}
Estoy usando la categoría UIImageView+AFNetworking
para la carga de imágenes asíncronas. Todo funciona bien, pero probé un par de cosas y no tuve éxito al cambiar el tamaño de la altura de la celda de acuerdo con la imagen descargada. Quiero que la imagen se ajuste al ancho de la celda pero que cambie de tamaño, pero no sé cómo lograr eso. Intenté volver a cargar la fila donde se descargó la imagen, pero eso solo hace que el cellForRowAtIndexPath
a disparar y vuelva a establecer todo, etc. Casi una recursión.
Estoy calculando la nueva diferencia de tamaño de imagen y almacenando eso en NSMutableArray
y luego NSMutableArray
cargar la fila en el bloque de éxito en setImageWithURLRequest de setImageWithURLRequest:placeholderImage:success:
Obtengo la altura correcta para un par de filas en heightForRowAtIndexPath
pero luego, la tabla comienza a actuar de forma extraña y todo se superpone, etc.
¿Algunas ideas?
¡Gracias!
EDITAR
Finalmente utilicé la respuesta de Ezeki. También escribí una publicación sobre el tema e hice una aplicación de muestra que usa esta técnica.
Compruébalo here .
Para mí esto funciona:
Verifica si la imagen de caché está disponible o no, si está disponible, si está configurada en la imagen y, si no, se descarga y luego el diseño de la restauración de la tabla llamando a rutas de índice de recarga.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *broadcastTableCellIdentifier = @"BlockbusterTableViewCell";
BlockbusterTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:broadcastTableCellIdentifier];
if (cell == nil) {
cell = [[BlockbusterTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:broadcastTableCellIdentifier];
}
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
-(void)configureCell:(BlockbusterTableViewCell*)cell atIndexPath:(NSIndexPath*)indexPath{
SportData *data = [self.webShared.arrSportsData objectAtIndex:self.selectedEvent];
BroadcastData *broadcastData = [data.broadcastData objectAtIndex:indexPath.row];
NSURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:broadcastData.image]];
AFImageDownloader *downloader = [UIImageView sharedImageDownloader];
id <AFImageRequestCache> imageCache = downloader.imageCache;
UIImage *cacheimage = [imageCache imageforRequest:urlRequest withAdditionalIdentifier:nil];
if (cell.imgBroadcast.image != cacheimage) {
[cell.imgBroadcast setImageWithURLRequest:urlRequest placeholderImage:[UIImage imageNamed:@"placeholder_smaller"] success:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, UIImage * _Nonnull image) {
cell.imgBroadcast.image = image;
[self.tableViewBroadcast beginUpdates];
[self.tableViewBroadcast reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.tableViewBroadcast endUpdates];
} failure:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, NSError * _Nonnull error) {
}];
}
else{
cell.imgBroadcast.image =cacheimage;
}
cell.lblTitle.text = broadcastData.title;
cell.lblText.text = broadcastData.text;
cell.lblEventDateTime.text = [self eventTime:broadcastData.eventTime];
}