UICollectionView无法重新加载单元格的imageView。

3

我需要在内部调用以下代码:

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath

很不幸,当我调用[collectionView reloadItemsAtIndexPaths:@[indexPath]];时,其中的imageView并没有更新。如果我调用reloadData,它会更新。我尝试使代码尽可能高效,所以不想只是调用reloadData。有人能解释一下为什么这个方法不起作用或者我需要做些什么吗?我已经遇到了一些其他问题,例如加载大量API图像查询与collectionView的 endAnimations 冲突等。如果有帮助的话,非常感谢。
  SearchResultsCollectionViewCell *searchResultCell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([SearchResultsCollectionViewCell class]) forIndexPath:indexPath];
    Product *product = self.products[indexPath.row];

    UIImage *productImage = [self.imageCache imageForURL:product.fullImageUrl];


    if (productImage) {
        searchResultCell.productImageView.image = productImage;
    } else {
        [self.imageCache downloadImageForURL:product.fullImageUrl indexPath:indexPath withCompletion:^(UIImage *image, NSError *error) {
            if (!error) {
                 searchResultCell.productImageView.image = image;
//                [collectionView reloadData];
                [collectionView reloadItemsAtIndexPaths:@[indexPath]];
            }

        }];
        UIImage* image = [UIImage imageNamed:@"001_logo"];
        searchResultCell.productImageView.image = image;
    }

需要注意的第一件事(但我不认为这是原因)是您将代码中的indexPath.row更改为indexPath.item - Fogmeister
1个回答

0

您访问和存储图像的方式似乎很奇怪。

我会这样做:在productImage上为UIImage创建一个@property

然后,您可以向产品请求其图像。如果产品返回空图像,则在单元格中放置占位符。

当下载完成时,您可以重新加载单元格。

其次,在您进行调用的下载调用的完成块中不要尝试更改单元格。

完成块应更新模型(即将图像存储到产品对象中),然后重新加载单元格。

原因是您无法确定运行完成块的单元格是(a)与启动完成块的单元格相同,还是(b)仍在显示相同的产品。


它应该可以,但实际上我并没有设计当前缓存图像的方式(这就是你看到的奇怪现象)。这很奇怪,因为我可以确认正确的图像已经下载并返回了...但当调用reloadItemsAtIndexPaths时,它似乎排队等待。如果我以这种方式执行此方法,那么最终会弹出一个错误,说我已经达到了UIView的动画限制,大约是31/32。我会认为它是通过索引路径引用的同一单元格。如果我将此completionBlock作为委托方法运行...它就可以正常工作。 - TheCodingArt
你已经在完成块中删除了设置图像的调用吗?完成块应该只运行reload... 另外,请确保它在主线程上。设置断点并查看线程号。它应该是1。如果不是,则需要将其推送到主线程上。 - Fogmeister
我已经尝试将所有内容包装在 'dispatch_async(dispatch_get_main_queue(), ^{' 中以确保它能够正常运行,但是没有成功。它不应该运行reload,而应该运行reloadItemsAtIndexPaths,因为当它们的图像从网络调用下载完成时,它会逐个刷新单个单元格。但是所有的操作都在主线程上进行(我希望这么容易)。 - TheCodingArt
那么...两年后你有什么特别的原因要给我点个踩呢? - Fogmeister

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接