我在求职面试中多次遇到这样的问题:你有一个UITableView,而用户的滚动速度非常快。您如何确保从服务器加载的所有单元图像在用户滚动到的任何位置都可见。
我可以想到几种技术。例如,我所做的是使用一个操作队列,加载了获取图像的请求,当用户开始滚动时,清空队列并在用户要去的任何地方填充图像请求。
另一种解决方案是用超低分辨率的缩略图填充图像,例如4点渐变,这样一些图像,尽管是坏的,在真实图像到达之前很久就存在了。
发布于 2015-04-29 22:51:23
我会说“清空队列,并在用户要去的任何地方用图像请求填充它”是使用indexPathsForVisibleRows的正确做法。但是,除非图像非常小,否则图像永远不会立即出现。
我认为他们的意思是在从后台线程下载后立即显示下载的图像,即:dispatch_get_main_queue()
在.h文件中:
@interface ViewController : UIViewController <UIScrollViewDelegate>在.m文件中:
- (void)downloadVisibleRowImages
{
NSArray *visibleRows = [self.tableView indexPathsForVisibleRows];
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
for (NSIndexPath *visibleRow in visibleRows) {
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath: visibleRow];
NSString *imageUrl = [_responseImages objectAtIndex:visibleRow.row];
UIImage *image = nil; // Download image here
dispatch_async(dispatch_get_main_queue(), ^{ // use main thread to display image immediately after download
if (image) [cell.imageView setImage:image];
});
}
});
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if (!decelerate) {
[self downloadVisibleRowImages];
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[self downloadVisibleRowImages];
}发布于 2015-04-29 22:57:11
我想说的是,这里的关键是“用户滚动到的位置”。因此,在知道哪些单元格将可见之前,您不应该开始下载图像。
所以我要做的就是观察UIScrollViewDelegate调用:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView此时,使用以下命令使单元格可见:
- (NSArray *)indexPathsForVisibleRows然后停止我的图片下载。把所有这些放在一起:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
NSArray *theIndexPaths = [self.tableView indexPathsForVisibleRows];
for (NSIndexPath *theIndexPath in theIndexPaths) {
SomeObject *myObject = self.listOfMyObjects[theIndexPath.row];
[myObject downloadImage];
}
}这是非常基础的。显然需要更新单元格,等等。
https://stackoverflow.com/questions/29946507
复制相似问题