首先,这不是重复。我看到了一些相同的问题,但由于我的问题有所不同,他们没有帮助我。
使用以下代码,我将在项目中异步下载图像。
{
NSURL *imageURL = [NSURL URLWithString:imageURLString];
[self downloadThumbnails:imageURL];
}
- (void) downloadThumbnails:(NSURL *)finalUrl
{
dispatch_group_async(((RSSChannel *)self.parentParserDelegate).imageDownloadGroup, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *tempData = [NSData dataWithContentsOfURL:finalUrl];
dispatch_async(dispatch_get_main_queue(), ^{
thumbnail = [UIImage imageWithData:tempData];
});
});
}
由于程序的逻辑,我在tableview控制器以外的文件中使用了上述代码,该控制器在从Web服务获取数据后显示所有数据。
问题:在我滚动之前,屏幕图像不会显示。屏幕外图像首先刷新。我该怎么做才能解决我的问题。
Apple的延迟加载项目使用scrollViewDidEndDragging和scrollViewDidEndDecelerating来加载图像,但项目太大而无法理解,而且我的代码在tableview控制器以外的文件中。
注意:请不要推荐像SDWebImage等第三方库。
更新:由于大多数人都无法解决问题,我必须澄清此问题与下载,缓存和重新加载tableview中的图像无关。所以请不要推荐第三方库。问题是图像仅在用户滚动tableview时显示,而不是加载屏幕上的图像。
提前致谢
答案 0 :(得分:4)
我认为你要做的是:
在下载图像时在表格单元格中显示一些占位符图像(否则您的表格看起来是空的);
当下载的图像存在时,向您的表发送刷新消息。
对于2,您有两种方法:
简单一个:将reloadData
发送到您的表格视图(并检查您应用的效果);
向您的表格视图发送消息:
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
使用reloadRowsAtIndexPaths
要好得多,但需要您跟踪哪个图片与哪个表格行相关联。
请注意,如果您使用Core Data存储图片,那么通过将NSFetchedResultController
与您的表格视图相结合,可以更轻松地完成此工作流程。 See here for an example
另一种方法是使用KVO:
在ItemsViewCell中声明这个观察方法:
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
if ([keyPath isEqual:@"thumbnail"]) {
UIImage* newImage = [change objectForKey:NSKeyValueChangeNewKey];
if (newImage != (id)[NSNull null]) {
self.thumbContainer.image = newImage;
[self.thumbContainer setNeedsLayout];
}
}
}
然后,当你配置单元格时:
RSSItem *item = [[channel items] objectAtIndex:[indexPath row]];
cell.titleLabel.text = [item title];
cell.thumbContainer.image = [item thumbnail];
[item addObserver:cell forKeyPath:@"thumbnail" options:NSKeyValueObservingOptionNew context:NULL];
通过这样做,只要给定的cell
“缩略图”密钥路径发生变化,就会通知item
。
另一个必要的变化是做这样的任务:
self.thumbnail = [UIImage imageWithData:tempData];
(即使用self.
)。
另一个编辑:
我想下载并加载图像,就像Apple的LazyTableImages示例一样。当它没有减速和拖动时,只加载屏幕上的图像,而不是一次加载所有图像。
我怀疑我们在这里谈论不同的问题。
我认为你的问题是下载的图像没有正确显示(如果你不滚动表格)。这是我从你的问题中理解的,我的建议解决了这个问题。
对于延迟加载,你正在做什么(下载整个feed然后整个归档)和你想要的(懒加载)之间存在某种不匹配。这两件事并不匹配,所以你应该重新考虑你在做什么。
除此之外,如果您想延迟加载图片,可以按照以下步骤操作:
请勿在{{1}}中加载图片,只需存储图片网址;
开始在parser:foundCDATA:
下载图片(如果您知道该网址,则可以在单独的帖子中使用dataWithContentOfURL);
我上面发布的代码会在图片出现时更新表格;
首先,不要担心滚动/拖动,只需1-2-3工作;
一旦工作,在滚动/拖动过程中使用滚动/拖动代理阻止图像下载(第2点);您可以在表格视图中添加一个标记,只有当标记显示“没有滚动/拖动”时才会tableView:cellForRowAtIndexPath:
下载图像。
我希望这足以让你达到最终结果。我不会为此编写代码,因为它非常简单。
PS:如果您懒得加载图片,您的Feed将存储在没有图像的磁盘上;你也可以删除CGD组和CGD等待。正如我所说,没有办法解决这个问题:你不能进行延迟加载,同时使用Feed归档图像(除非每次你得到一个新的图像,你归档整个feed) 。你应该找到另一种缓存图像的方法。
答案 1 :(得分:3)
尝试使用SDWebImage,它非常适合在UITableViews中使用来自网络的图片,并为您处理大部分工作。
答案 2 :(得分:0)
最好的想法是缓存图像并使用它们。我已经编写了表视图的代码。 Image on top of Cell 这是一个很好的解决方案。
答案 3 :(得分:0)
尝试使用此代码下载图片
- (void) downloadThumbnails:(NSURL *)finalUrl
{
NSURLRequest* request = [NSURLRequest requestWithURL:finalUrl];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse * response,
NSData * data, NSError * error)
{
if (!error)
{
thumbnail = [UIImage imageWithData:data];
}
}];
}