UICollectionView在错误的位置加载单元格数据

时间:2014-11-04 14:50:19

标签: ios objective-c uicollectionview

我有一个显示自定义单元网格的UICollectionView。当我在cellForItemAtIndexPath中设置单元格时,我在单元子类上调用一个方法来设置UI(例如[cell setupUI])。此方法执行一些标签加载,但也调用异步方法从Web获取图像。我正在使用AFNetworking来处理这个问题。

我的问题是,有时(经常)图像被加载到正确的单元格+不应该有图像集的单元格中。数据似乎被加载到随机单元格中。

我已经看了一段时间并尝试了多种方法,但我无法弄清楚我哪里出错了。我有什么遗失吗?

注意:我已经检查过,设置这些图像单元的方法被称为正确的次数(3),但图像出现在5个单元格上。

修改

这是用于获取图像的代码。我以前在没有CollectionView的情况下使用它(自己绘制网格)并且它工作正常:

  [self.youtubeThumbnail setImageWithURLRequest:request placeholderImage:nil success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image){
        weakImageView.image = image;
 } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error){

 }];

weakImageView是我的单元格图像视图的弱引用。上面的代码在cell子类中,从cellForItemAtIndexPath调用。

我应该指出这个方法是在dispatch_async(dispatch_get_global_queue)上运行的,而图像加载是在dispatch_async(dispatch_get_main_queue)上。

解决方案

所以我的问题其实很奇怪。我的集合视图被多次重新加载,这导致数据在不正确的单元格中多次出现。我仍然不能100%确定为什么会这样,但我已经设法通过检查内容是否已重新加载,设置BOOL以及防止再次重新加载来破解它。 我选择的答案是正确的帮助我得到异步加载正确,这也可能是问题的一部分。 谢谢你的帮助。

2 个答案:

答案 0 :(得分:0)

如果您愿意使用任何第三方库,我建议您查看SDWebImage。它解决了异步下载内容时不正确的单元格具有错误数据的问题。

它的代码类似于:

[cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
                   placeholderImage:[UIImage imageNamed:@"placeholder.png"]];

它使用简单的方法扩展UIImageView,轻松拥有您的收藏并保持正确的图像。这也适用于标准的UITableViewCells。

答案 1 :(得分:0)

问题可能与细胞重用有关(但不提供代码,我只是在猜测)。当您滚动浏览集合视图时,屏幕上显示的单元格将被回收,稍后会重复使用以避免在滚动时创建大量对象的开销。 UICollectionView类引用中有更多信息。

更具体地说,您看到的问题可能是,当您的网络响应发生故障时,最初创建请求的单元格将在屏幕外。您可以通过关注Apple旧的LazyTableImages示例应用来解决此问题。关键是在RootViewController中实现startIconDownload:forIndexPath:

[iconDownloader setCompletionHandler:^{

        UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];

        // Display the newly loaded image
        cell.imageView.image = appRecord.appIcon;

        // Remove the IconDownloader from the in progress list.
        // This will result in it being deallocated.
        [self.imageDownloadsInProgress removeObjectForKey:indexPath];

    }];

因此,当图像完成下载时,表视图会将正确的单元格移动到设置imageView的完成块。因此,您将拥有正确的表视图单元格或(或者在您的情况下,集合视图单元格)。并且,如果单元格触发了一个请求但是在它关闭之前滚动到屏幕外,则没有什么可以担心的,因为TableView / CollectionView方法将为屏幕外单元格返回nil。