我正在制作一个简单的图库iOS程序,并对UICollectionView数据源行为有疑问。
在我的代码中一切正常,只是当我向上或向下滚动时每个单元格的图像都会闪烁。
不可见的单元格在可见之前不会下载图像。 在我的代码中,它是按需下载的。这是最佳做法吗?这就是为什么我得到闪烁的细胞?
细胞的可重用性让我感到困惑。在我的观察中,当细胞变得不可见时,细胞会失去自己的图像。我怎么能阻止这个?这也是我得到闪烁细胞的原因吗?
这是代码。
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
FBPhotoCollectionViewCell *cell = (FBPhotoCollectionViewCell*)[collectionView dequeueReusableCellWithReuseIdentifier:@"PhotoCell" forIndexPath:indexPath];
__weak FBPhotosVC *weakSelf = self;
if ([_PhotoLinks count] > 0) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSURL* theURL = [NSURL URLWithString:[_PhotoLinks objectAtIndex:(int)indexPath.row]];
UIImage* tempImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:theURL]];
if ([weakSelf.theCollectionView.indexPathsForVisibleItems containsObject:indexPath]) {
if (tempImage)
{
dispatch_async(dispatch_get_main_queue(), ^{
FBPhotoCollectionViewCell *cell = (FBPhotoCollectionViewCell *)[weakSelf.theCollectionView cellForItemAtIndexPath:indexPath];
cell.theImageView.image = tempImage;
});
}
else
{
// Download failed.
NSLog(@"Downloaded image is nil.");
}
}
});
}
cell.backgroundColor = [UIColor grayColor]; <br>
return cell; <br>
}
答案 0 :(得分:0)
尝试删除此内容:
if ([weakSelf.theCollectionView.indexPathsForVisibleItems containsObject:indexPath])
您无需检查单元格是否可见。 cellForItemAtIndexPath仅在新单元格可见时调用,当此单元格从屏幕上消失时,它将被重用。
此外,我认为您不需要多线程来加载这样的图像。尝试将其删除两次。
您可以做的是将已下载的图像存储在数组或字典中,并在每次调用cellForItemAtIndexPath时进行检查。
(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
FBPhotoCollectionViewCell cell = (FBPhotoCollectionViewCell)[collectionView dequeueReusableCellWithReuseIdentifier:@"PhotoCell" forIndexPath:indexPath];
if ([_PhotoLinks count] > 0)
{
NSString photoName = [_PhotoLinks objectAtIndex:(int)indexPath.row];
UIImage* tempImage = [self.cacheDictionnary objectForKey:photoName];
if (!tempImage)
{
NSURL* theURL = [NSURL URLWithString:photoName];
tempImage= [UIImage imageWithData:[NSData dataWithContentsOfURL:theURL]];
}
if (tempImage)
{
[self.cacheDictionnary setObject:tempImage forKey:photoName];
cell.theImageView.image = tempImage;
}
else
{
// Download failed.
NSLog(@"Downloaded image is nil.");
}
}
cell.backgroundColor = [UIColor grayColor];
return cell;
}
答案 1 :(得分:0)
TrainingGoalsCell cell =(TrainingGoalsCell )[collectionView dequeueReusableCellWithReuseIdentifier:@&#34; Cell&#34; forIndexPath:indexPath];
NSString *thePath=[[NSBundle mainBundle] pathForResource:[arrayVideos objectAtIndex:indexPath.row] ofType:@"mp4"];
NSURL *url = [NSURL fileURLWithPath:thePath];
CGRect attachmentFrame = CGRectMake(2, 2, cell.frame.size.width-4, cell.frame.size.height-4);
if(!isScrolling){
UIView* subView;
// asset is a video
self.avPlayer = [[AVPlayer alloc] initWithURL:url];
self.avPlayer.muted = YES;
self.avPlayerLayer =[AVPlayerLayer playerLayerWithPlayer:self.avPlayer];
[self.avPlayerLayer setFrame:CGRectMake(0, 0, cell.frame.size.width-4, cell.frame.size.height-4)];
if(!subView){
subView = [[UIView alloc]initWithFrame:attachmentFrame];
[subView.layer addSublayer:self.avPlayerLayer];
[[cell.contentView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
[cell.contentView addSubview:subView];
}
[self.avPlayer seekToTime:kCMTimeZero];
self.avPlayerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[self.avPlayer play];
self.avPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerItemDidReachEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:[self.avPlayer currentItem]];
}