UITableView屏幕上的图像下载延迟加载
首先这不是重复的。 我看到了一些相同的问题,但他们没有帮助我,因为我的问题有一点变化。
使用下面的代码我在我的项目中asynchronous下载图像。
{ 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服务获取它的文件。
问题:在屏幕上图像不显示,直到我滚动。 屏幕图像首先被刷新。 我能做些什么来解决我的问题。
苹果的延迟加载项目是使用scrollViewDidEndDragging和scrollViewDidEndDecelerating加载图像,但项目是太大了无法理解,加上我的代码是在除了tableview控制器以外的文件。
注意:请不要推荐像SDWebImage等第三方库
更新:由于大多数人无法得到的问题,我必须澄清,这个问题是不是与下载,caching和重新加载tableview中的图像相关联。 所以请不要推荐第三方库。 问题是图像只显示在用户滚动tableview,而不是加载屏幕上的。
提前致谢
我认为你必须做的是:
-
当图像被下载时,在表格单元格中显示一些占位符图像(否则你的表格将看起来是空的);
-
当下载的图像在那里,发送一个刷新消息到你的表。
2,你有两种方法:
-
简单的一个:发送
reloadData
到你的表格视图(并检查你的应用程序的性能); -
发送你的表查看消息:
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
使用reloadRowsAtIndexPaths
要好得多,但是需要跟踪哪个图像与哪个表格行相关联。
请记住,如果您使用Core Data存储图像,那么通过将NSFetchedResultController
与您的表视图集成将使这个工作stream程变得更容易。 看这里的例子 。
再一种方法是使用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]; } } }
-
那么当你configuration单元的时候呢:
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];
通过这样做,每当给定item
“缩略图”键path改变时, cell
将被通知。
另一个必要的改变是这样做的任务:
self.thumbnail = [UIImage imageWithData:tempData];
(即使用self.
)。
另一编辑:
我想下载和加载图像就像苹果的LazyTableImages示例。 当不减速和拖动,只有屏幕上的图像加载,并不是所有的图像一次加载。
我怀疑我们在这里谈论不同的问题。
我以为你的问题是,下载的图像显示不正确(如果你不滚动表)。 这是我从你的问题中了解到的,我的build议修复了这个问题。
至于延迟加载,你在做什么(下载整个提要,然后整体归档)和你想要什么(延迟加载)之间存在某种不匹配。 这两件事情不一致,所以你应该重新思考你在做什么。
除此之外,如果您想延迟加载图像,您可以按照下列步骤操作:
-
不要在
parser:foundCDATA:
加载图像parser:foundCDATA:
只是存储图像的URL; -
开始下载
tableView:cellForRowAtIndexPath:
的图像tableView:cellForRowAtIndexPath:
如果你知道的URL,你可以使用dataWithContentOfURL,因为你正在做一个单独的线程); -
我上面发布的代码将使图像在那里时表更新;
-
首先,不要担心滚动/拖动,只要1-2-3工作;
-
一旦工作,使用滚动/拖动代表来防止图像在滚动/拖动期间下载(点2); 您可以添加一个标志到您的表视图,并使
tableView:cellForRowAtIndexPath:
只有在标志显示“不滚动/拖动”下载图像。
我希望这足以让你达到最终结果。 我不会为此编写代码,因为它非常简单。
PS:如果您懒惰加载图像,您的饲料将存储在磁盘上没有图像; 你可以把CGD组和CGD等一下。 正如我所说,没有办法,你不能做延迟加载,并在同一时间存档图像与饲料(除非每次你得到一个新的形象,你存档整个饲料)。 你应该find另一种caching图像的方法。
尝试使用SDWebImage ,它非常适合在UITableViews中使用来自Web的图像,并为您处理大部分工作。
最好的想法是caching图像并使用它们。 我已经写了表视图的代码。 在单元格顶部的图像这是一个很好的解决scheme。
尝试使用此代码下载图片,
- (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]; } }]; }