19

我正在使用UIImageView+AFNetworking类别进行异步图像加载。一切正常,但我尝试了几件事,但在根据下载的图像调整单元格的高度时没有成功。我希望图像适合单元格的宽度,但要调整高度,但我不知道如何实现。我尝试重新加载下载图像的行,但这只会导致cellForRowAtIndexPath再次触发并再次设置所有内容,等等。几乎是递归。

我正在计算新的图像大小差异并将其存储NSMutableArray在 UIImageView 的成功块中,然后重新加载该行setImageWithURLRequest:placeholderImage:success:

我得到了几行的正确高度,heightForRowAtIndexPath但随后,表格开始表现得很奇怪,一切都重叠了,等等。

有任何想法吗?

谢谢!

编辑

我最终使用了 Ezeki 的答案。我还写了一篇关于该主题的文章,并制作了一个使用这种技术的示例应用程序。

这里查看

4

2 回答 2

19

您需要将下载的图像存储在内存或磁盘上,因此下次尝试从该 URL 获取图像时,您将从缓存中接收到图像。

因此,如果您这样做,则必须执行以下操作:

[tableView beginUpdates];

[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];

[tableView endUpdates];

并且您应该在表格视图数据源的这种方法中返回新单元格的高度:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

我建议您使用SDWebImage 库AFNetworking因为它可以为您将图像缓存到内存缓存和磁盘,并且非常易于使用。因此,如果您决定使用它,您的下载图像代码将如下所示:

- (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;
}
于 2012-10-27T23:52:07.207 回答
0

对我来说,这有效:

您检查缓存图像是否可用,如果可用,则将其设置为图像,如果不可用,则将其下载,然后通过调用重新加载索引路径重置表的布局。

-(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];
}
于 2016-11-30T13:33:08.543 回答