我有一个带有UICollectionViewFlowLayout
的collectionView,具有一定的可重用性:
- (CategoryCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
CategoryCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CategoryCell" forIndexPath:indexPath];
[cell.actIn startAnimating];
cell.cellElementRepresentation = [self.localCategoriesObjects objectAtIndex:indexPath.row];
[cell tryToShow]; //this is a important method to my problem
return cell;
}
我评论了你tryToShow
方法。我认为这是一个问题。当我滚动到列表中不可见的元素时,我可以先看到“旧”元素,然后是新元素。这是为什么?我的tryToShow
方法基本上就是下载管理器。我试着在评论中描述它。这是代码:
-(void)tryToShow {
NSString* imageFile = self.linkToImageFileSavedOnDisk //This is my local file saved in documentsDirectory.
if([[NSFileManager defaultManager] fileExistsAtPath:imageFile]) {
[self.overlayButton setBackgroundImage:[UIImage imageWithContentsOfFile:imageFile] forState:UIControlStateNormal];
[self disableActIn]; //Here i stop and remove activity indicator.
} else {
// Here i fire NSURLConnection and try to download. When NSURLConnection finished i put image to overlayButton.
}
}
这是委托方法:
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
//Here do some stuff to convert Data into UIImage... not important.
[self.overlayButton setBackgroundImage:object forState:UIControlStateNormal];
}
overlayButton是UICollectionViewCell
上的一个按钮。我有一个自定义类。
我无法理解。滚动后,如何从indexPath.row
(例如1)成像?新成功下载后,图像会被新图像替换,但现在已经很晚了。
答案 0 :(得分:1)
正如OP提到的,问题似乎是你设置backgroundImage
为时已晚。所以我会尝试这些修改:
首先,在设置新值之前清除您的单元格。由于您正在重复使用单元格,旧值(文本和图像)仍将出现在单元格子视图中。将这些值设置为nil将清除您的单元格。
实施一种机制来验证或使图像请求的结果无效,因为可能会得到结果太晚,可能不再需要。最糟糕的是,您可以将图像设置为不再与您的数据相对应。在设置下载的图像之前,您应该检查此图像是否与当前显示的数据一致。
在开始图像请求之前稍等一下如果您有大量的单元格,您应该认为当用户快速滚动集合时,您可以启动大量图像请求可能永远不会显示。我会在开始新请求之前稍等一会儿,并检查该单元格是否已被重新使用,以避免此行为。
使用NSURLRequest并将cachePolicy属性配置为NSURLRequestReturnCacheDataElseLoad
。这将存储图像的响应,无需显式保存图像保存图像并检查图像是否存在。
答案 1 :(得分:0)
我认为您需要在启动Web请求的else子句中将self.overlayButton
的背景图像设置为nil。
[self.overlayButton setBackgroundImage:nil forState:UIControlStateNormal];
这样,当用户滚动到单元格时,单元格似乎不会加载图像。或者,如果加载速度不够快(它应该加载),您可以在collectionView:didEndDisplayingCell:forItemAtIndexPath:
委托方法中将背景图像设置为nil。
但我发现的一个问题是,每次调用NSURLConnection
时,您都会创建重复的tryToShow
个对象,即用户向下滚动然后重新访问顶部的单元格。
正如@ lucaslt89建议的那样,你可以创建一个单元格字典,而不是使用默认的出列。如果这样做,请确保您在单元格上具有URL连接对象的属性,并在开始新单元之前检查它。
或者,您可能希望创建在视图控制器中创建的任何NSURLConnection
对象的字典,并将Web请求代码移动到视图控制器中。如果需要Web请求,视图控制器将首先检查字典中是否已经存在Web请求。请求完成后,请求对象将从字典中删除。这将是理想的方法,因为单元格不负责创建自己的数据。在UICollectionView
中,细胞必须快速改变角色,将特定细胞与某些数据相关联是不明智的,除非细胞真的很少。
无论哪种方式,您都可以避免为同一图片创建多个网址请求。
希望这有帮助!