单元格背景图像已下载,但在完成下载后需要 5 秒才能出现
Posted
技术标签:
【中文标题】单元格背景图像已下载,但在完成下载后需要 5 秒才能出现【英文标题】:cell Background images are downloaded but take 5 seconds to appear right after finishing download 【发布时间】:2014-06-14 22:28:43 【问题描述】:我希望 UITableView 在被点击后立即出现。在 UITableView 的每个单元格中都有一个从 Flickr 获取的背景图像,因此必须在后台线程中下载图像。
所以一切正常,图像在单独的线程中成功下载。但问题是,您必须在下载完成后等待 5 秒,图片才能真正出现在每个单元格中:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString *CellIdentifier = @"rightMenuCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
UILabel *lblTitle = (UILabel *)[cell viewWithTag:1];
UIImageView *imgCube = (UIImageView *)[cell viewWithTag:2];
UIActivityIndicatorView *spinnerFlickr = (UIActivityIndicatorView *)[cell viewWithTag:4];
// Configure the cell...
NSDictionary *region = self.regions[indexPath.row];
//default hashtag is life
NSString *hashTag;
cell.detailTextLabel.text = [region valueForKeyPath:@"name"];
cell.detailTextLabel.hidden = TRUE;
lblTitle.text = [region valueForKeyPath:@"name"];
NSString *regionType = [region valueForKeyPath:@"region"];
if ([regionType isEqual: @"neighborhood"])
hashTag = @"houses";
cell.textLabel.text = @"neighborhood";
else if ([regionType isEqual: @"locality"])
hashTag = @"urban";
cell.textLabel.text = @"locality";
else
hashTag = @"life";
cell.textLabel.text = @"administrative_area_level_2";
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0),
^
UIImageView *imgBackground = (UIImageView *)[cell viewWithTag:3];
[imgBackground setClipsToBounds:YES];
NSLog(@"loading image data...");
NSString *flickrURL = [NSString stringWithFormat:@"http://domfa.de/get_image/?text=%@&lat=%f&long=%f", hashTag, self.latitude, self.longitude];
NSData *image = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: flickrURL]];
UIImage *cellBG = [[UIImage alloc] init];
cellBG = [UIImage imageWithData:image];
imgBackground.image = cellBG;
[imgBackground reloadInputViews];
NSLog(@"images loaded!");
imgBackground.image = cellBG;
[spinnerFlickr stopAnimating];
);
return cell;
基本上每个单元格都会异步下载背景图像,但即使在下载完成后,我也必须点击一个单元格或等待 5 秒,然后 2/3 的单元格将加载图像。
【问题讨论】:
确保你的表格视图在主线程上。 【参考方案1】:dispatch_get_global_queue()
获取后台队列,而不是主队列。你只能在主队列中做与 UI 相关的事情。您的图像提取应该如下所示:
dispatch_async(dispatch_get_global_queue(…) ,
^
// Do non-UI-related things like fetch your UIImage from the network
UIImage *image = [self fetchAndCacheImageAtURL:imageURL] ;
dispatch_async(dispatch_get_main_queue() ,
^
// Assign your UIImage to your UIImageView
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath] ;
if( cell )
cell.imageView.image = image ;
) ;
) ;
请注意,在第二个dispatch_async()
中,我再次使用-cellForRowAtIndexPath:
获取单元格。这是因为在这段代码运行时,原始单元格可能已被重新用于 不同 索引路径(因为,例如,用户一直在滚动)。实际上,当前索引路径可能没有单元格,因为该索引路径可能已滚动到屏幕外。这一点,加上检查单元格是否为零,确保您将图像设置在该索引路径的正确单元格上。
【讨论】:
另外,一旦你回到主队列,你需要考虑cell
由于滚动而被重复使用的可能性。
@AaronBrager,leftspin 的代码确实允许这样做。他正在使用 tableView 方法 cellForRowAtIndexPath,它将获取指定 indexPath 的 CURRENT 单元格,即使它是不同的单元格,或者不再在屏幕上。以上是关于单元格背景图像已下载,但在完成下载后需要 5 秒才能出现的主要内容,如果未能解决你的问题,请参考以下文章