ios 7 - 异步图像下载 UITableView 用于未知尺寸的图像

Posted

技术标签:

【中文标题】ios 7 - 异步图像下载 UITableView 用于未知尺寸的图像【英文标题】:ios 7 - Async Image Download UITableView For Image with Unknown Dimension 【发布时间】:2015-06-01 14:23:02 【问题描述】:

我正在使用面向 ios 7 的 XCode 6.3.1。

我正在使用AFNetworkingUIImageView 类别将未知尺寸的图像下载到UITableViewCell 的。这是一个示例图像:

我遇到的问题是,由于图像的尺寸未知,我只使用占位符图像。如果占位符图像具有完全相同的尺寸,则没有问题。但是,如果尺寸不同,则单元格中的间距会出现问题。

如果图片小于,间距会太大。这是一个例子:

我不知道在我完成下载图像后如何刷新单元格,以便间距符合我的Auto Layout Constraints

如果我滚动离开单元格并向后滚动,间距很好。

这里是一些图片下载的示例代码

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

        // Temp
    static NSString *Cell = @"CustomListCell";
    CustomListCell *cell = (CustomListCell *)[self.tableView dequeueReusableCellWithIdentifier:Cell];
    CustomListRow *customListRow = self.customList.rows[indexPath.row];

    // Reset the cell
    cell.headerImageView.image = nil;
    cell.titleLabel.text = @"";

    // Download the image, placeholder image is necessary
    NSString *topImageURL = @"sample_image";
    __weak __typeof(cell)weakCell = cell;
    if ([topImageURL isEqualToString:@""] || [topImageURL isEqualToString:@"false"])
    
        // Do nothing
     else 
        [cell.headerImageView setImageWithName:topImageURL afterManipulation:^UIImage *(UIImage *image) 
            // Manipulation
            UIImage *newImage = [UIImage expandImage:image toWidth:Constants.screenWidth - 16];

//            CustomListCell *updateCell = (CustomListCell *)[tableView cellForRowAtIndexPath:indexPath];
//            if (updateCell)
//                updateCell.headerImageView.image = newImage;
            return newImage;
         placeholderImage:[UIImage expandImage:Constants.placeholderImage toWidth:Constants.screenWidth - 26]];
    

    return cell;

setImageWithName:afterManipulation:placeholderImage: 是我用来环绕AFNetworkingsetImageWithURL...的一种方法。它首先检查图像是否存在于本地,然后再检查两个不同的 URL(绝对和 base_url + 相对)是否存在图像那里。

我将操作块放在那里,以便我可以调用我创建的 UIImage 类别方法,该方法将缩放图像以适应 UITableView 的宽度(因此唯一的动态部分是高度)。

这是我尝试过的事情的清单:

重新加载特定单元格 重新加载整个表 [self.tableView beginUpdates] + [self.tableView endUpdates]; 致电[cell setNeedsLayout],或[cell setNeedsDiplay];

setNeedsLayoutsetNeedsDisplay 在我完成加载图像后没有做任何事情(我将它放在在分配图像之前调用的 afterManipulation 块中,我也尝试在分配图像之后放置它)。

重新加载单元格、表格或 beginUpdates 会导致一些非常奇怪的行为发生。细胞开始混合在一起,一些细胞具有相同的图片(这不应该发生)。我不确定发生了什么,但我的猜测是重新加载单元格会导致图像再次下载(或从缓存中拉出),直到加载另一个单元格后才会完成。

【问题讨论】:

【参考方案1】:

您是否考虑过使用图像视图的contentMode 属性?

用于确定视图在其边界发生变化时如何布置其内容的标志。

我在查看您的实现时观察到的一个问题是,您可能会在单元格中得到错误的图像。我看到您在下载图像时将单元格作为参考。这是错误的,原因如下:

表格视图单元格可以重复使用,因此当您滚动时,离开屏幕的单元格将再次用于显示其他行的信息。通过引用单元格而不是索引路径,如果您的下载需要时间,则在调用完成块时,该单元格可能会显示不同行的信息,因此,您在其上应用的图像可能不是正确的.

您应该看看 Apple 的示例,了解如何在为每个表格视图单元格下载图像时保持一致性:https://developer.apple.com/library/ios/samplecode/LazyTableImages/Introduction/Intro.html#//apple_ref/doc/uid/DTS40009394-Intro-DontLinkElementID_2

【讨论】:

我相信 AFNetworking 的 UIImageView 应该解决这个问题。如果调用了新请求,它应该取消旧请求并用新请求替换它。在他们的示例代码中,他们没有对索引路径(或单元格以外的其他内容)的任何引用

以上是关于ios 7 - 异步图像下载 UITableView 用于未知尺寸的图像的主要内容,如果未能解决你的问题,请参考以下文章

iOS Swift CoreData 异步下载图片数据

在 UITableView 的单元格中下载图像的最佳实践? iOS/斯威夫特

Scala 中的异步 IO 与期货

异步数据附加到ios中的文件?

异步 NSImage 下载:第一个图像无限加载

使用 AFNetworking 异步下载图像后,是不是可以从 UIImageView 获取图像