在UITableView中延迟UIImageView渲染

时间:2009-12-01 15:27:03

标签: iphone uiimageview uitableview nsurlconnection

好的,我有一个UITableView个自定义UITableViewCell,每个都包含一个UIImageView,其图片是通过NSURLConnection异步下载的。所有非常标准的东西......

问题是,当桌子滚动时,新图像会在后台正确下载,但在表停止移动之前不会出现RENDERED。

即使表格移动,我如何让表格呈现内容? 感谢。

- 更新 -

仔细观察后,我发现NSURLConnection委托方法在表停止滚动之前不会触发。不知道为什么。任何帮助都会很棒。

4 个答案:

答案 0 :(得分:65)

在您停止滚动之前连接委托消息未触发的原因是因为在滚动期间,运行循环位于UITrackingRunLoopMode。默认情况下,NSURLConnection仅在NSDefaultRunLoopMode中自行安排,因此您在滚动时不会收到任何消息。

以下是如何在“常用”模式下安排连接,其中包括UITrackingRunLoopMode

NSURLRequest *request = ...
NSURLConnection *connection = [[NSURLConnection alloc]
                               initWithRequest:request
                               delegate:self
                               startImmediately:NO];
[connection scheduleInRunLoop:[NSRunLoop currentRunLoop]
            forMode:NSRunLoopCommonModes];
[connection start];

请注意,您必须在初始化程序中指定startImmediately:NO,这似乎与Apple的文档背道而驰,该文档建议您即使在启动后也可以更改运行循环模式。

答案 1 :(得分:1)

您应该阅读NSRunLoop。我怀疑,在滚动期间,运行循环在NSEventTrackingRunLoopMode中运行,并且NSURLConnection不包含在该模式中。您可以通过调用NSURLConnection的scheduleInRunLoop:forMode:来解决这个问题,以便在滚动期间进行下载。

这可能会影响滚动性能,这可能是首先单独运行循环模式的原因。但试一试,看看感觉如何!

答案 2 :(得分:1)

如果你包装你的图像下载&在NSOperation中更新,更新将在表视图滚动时发生。

NSOperation的另一个好处是,当细胞在屏幕外滑动时,您可以取消操作。它会对用户产生更多响应...特别是如果他们快速滚动一个长列表。今年的Apple技术讲座鼓励了这种技术。

如果您的列表不长,或者您希望它们继续加载,则可以改为操作NSOperation优先级。

答案 3 :(得分:0)

首先......你的连接可能甚至没有开始,直到它进入mainRunLoop并且滚动动画也在处理。

我遇到了同样的问题并通过告诉图像的连接在创建后立即启动来修复它。

    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:wrapper.request delegate:wrapper];

    [connection start];

在您收到图像并将cell.imageView.image设置为接收图像的完成例程中,您应该检查此单元格是否属于当前正在表格中显示的其中一个单元格...如果所以调用[tableView reloadData]。

    NSInteger itemIndex = theIndexInTheRowDataOfTheCellYouStuffedTheImage

    NSArray *indicies = [_tableView indexPathsForVisibleRows];
    NSUInteger rows = indicies.count;

    if (rows > 0 &&
        itemIndex >= ((NSIndexPath *)[indicies objectAtIndex:0]).row &&
        itemIndex <= ((NSIndexPath *)[indicies objectAtIndex:rows - 1]).row)
    {       
        [_tableView reloadData];
    }
相关问题